home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Think Class Libraries / WASTE TCL 2.0b2 / WASTEEdit / Aliases / WASTE TCL 2.0 ƒ / CWASTEText.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-16  |  84.4 KB  |  3,481 lines  |  [TEXT/SPM ]

  1. /********************************************************\
  2.  CWASTEText.cpp
  3.  
  4.     by Dan Crevier
  5.     version 1.9
  6.     1/2/95
  7.  
  8.     Roms    95/11/08    adapted to THINK C / TCL 1.1.3
  9. \********************************************************/
  10.  
  11. #ifdef TCL_PCH
  12. #include <TCLHeaders>
  13. #endif
  14.  
  15. #include "CWASTEText.h"
  16. #if WASTE_VERSION >= 0x01100000
  17. #include "CWASTETask.h"
  18. #else
  19. #include "CWASTEEditTask.h"
  20. #include "CWASTEStyleTask.h"
  21. #endif
  22.  
  23. #ifndef __ERRORS__
  24. #include <Errors.h>
  25. #endif
  26. #ifndef __SCRAP__
  27. #include <Scrap.h>
  28. #endif
  29. #ifndef __FONTS__
  30. #include <Fonts.h>
  31. #endif
  32. #ifndef __DRAG__
  33. #include <Drag.h>
  34. #endif
  35. #ifndef __SOUND__
  36. #include <Sound.h>
  37. #endif
  38. #ifndef __ICONS__
  39. #include <Icons.h>
  40. #endif
  41. #ifndef __SCRIPT__
  42. #include <Script.h>
  43. #endif
  44. #ifndef __TEXTSERVICES__
  45. #include <TextServices.h>
  46. #endif
  47.  
  48. #include "CClipboard.h"
  49. #include "CBartender.h"
  50. #include "Commands.h"
  51. #include "TCLUtilities.h"
  52. #include "Constants.h"
  53. #include "CScrollPane.h"
  54. #include "Global.h"
  55. #include "CPrinter.h"
  56. #include "CWindow.h"
  57. #include "CDataFile.h"
  58. #include "CResFile.h"
  59.  
  60. // Global Variables
  61. extern CClipboard    *gClipboard;    // Copies and Pastes data
  62. extern EventRecord  gLastMouseUp;
  63. extern CBureaucrat    *gGopher;
  64. extern CBartender    *gBartender;
  65.  
  66. extern long        gSleepTime;
  67. extern short        gUsingTSM;
  68. extern Boolean    gHasDragAndDrop;
  69.  
  70. // compiler options -- override defaults in the prefix
  71. // are we using the WASTE-supplied object archive?
  72. #ifndef WASTE_OBJECT_ARCHIVE
  73.     #define WASTE_OBJECT_ARCHIVE 0
  74. #endif
  75.  
  76. // are we going to support tabs?
  77. #ifndef WASTE_TABS
  78.     #define    WASTE_TABS    0
  79. #endif
  80.  
  81. // are we going to install tabs by default?
  82. #ifndef WASTE_AUTO_TABS
  83.     #define WASTE_AUTO_TABS    0
  84. #endif
  85.  
  86. // this should match the definition for C
  87. #ifndef WASTE_OBJECTS
  88.     #define WASTE_OBJECTS 1
  89. #endif
  90.  
  91. // should we use VA Compatible Object I/O routines?
  92. #ifndef VA_COMPATIBLE_IO
  93.     #define VA_COMPATIBLE_IO 0
  94. #endif
  95.  
  96. #if WASTE_OBJECT_ARCHIVE
  97. #include "WASTE_Objects.h"
  98. #endif
  99.  
  100. #if WASTE_VERSION == 0x01100000
  101.     // undocumented WASTE routine
  102.     // Note: You need to #define CWASTE if you are using CWASTE 1.0
  103.     #ifdef CWASTE
  104.         extern "C"
  105.         {
  106.             long _WEOffsetToLine(long offset, WEHandle hWE);
  107.         }
  108.     #else
  109.         pascal long _WEOffsetToLine(long offset, WEHandle hWE);
  110.     #endif
  111. #endif
  112.  
  113. #if WASTE_TABS
  114. #include "WETabs.h"
  115. #endif
  116.  
  117. #if WASTE_VERSION >= 0x01100000
  118. // for drag and drop
  119. static DragTrackingHandler trackingUPP = NULL;
  120. static DragReceiveHandler receiveUPP = NULL;
  121. static pascal OSErr WASTETrackingHandler(DragTrackingMessage theMessage, WindowPtr theWindow,
  122.     void *handlerRefCon, DragReference theDrag);
  123. static pascal OSErr WASTEReceiveHandler(WindowPtr theWindow, void *handlerRefCon, DragReference theDrag);
  124.  
  125. #define kTypePicture        'PICT'
  126. #define kTypeSound            'snd '
  127. #define kTypeSoup            'SOUP'
  128.  
  129. #if WASTE_OBJECTS && !WASTE_OBJECT_ARCHIVE
  130.     // handlers for pictures and sounds
  131.     #define kSoundIconNumber    777
  132.     static pascal OSErr HandleNewPicture(Point *defaultObjectSize, WEObjectReference objectRef);
  133.     static pascal OSErr HandleDisposePicture(WEObjectReference objectRef);
  134.     static pascal OSErr HandleDrawPicture(Rect *destRect, WEObjectReference objectRef);
  135.     static pascal OSErr HandleNewSound(Point *defaultObjectSize, WEObjectReference objectRef);
  136.     static pascal OSErr HandleDisposeSound(WEObjectReference objectRef);
  137.     static pascal OSErr HandleClickSound(Point hitPt, short modifiers, long clickTime,
  138.         WEObjectReference objectRef);
  139.     static pascal OSErr HandleDrawSound(Rect *destRect, WEObjectReference objectRef);
  140. #endif // WASTE_OBJECTS && !WASTE_OBJECT_ARCHIVE
  141.  
  142. #endif // WASTE 1.1
  143.  
  144. CWASTEText *CWASTEText::curWASTEText = NULL;
  145.  
  146. #if (TCL_VERSION) >= 0x02000000
  147. TCL_DEFINE_CLASS_D1(CWASTEText, CAbstractText);
  148. #endif
  149.  
  150. RGBColor RGBBlack={0,0,0};
  151. RGBColor RGBRed={65535,0,0};
  152. RGBColor RGBGreen={0,65535,0};
  153. RGBColor RGBBlue={0,0,65535};
  154. RGBColor RGBCyan={0,65535,65535};
  155. RGBColor RGBMagenta={65535,0,65535};
  156. RGBColor RGBYellow={65535,65535,0};
  157.  
  158. /********************************************************\
  159.  CWASTEText() - default constructor
  160.      You must call IWASTEText if you use this
  161. \********************************************************/
  162.  
  163. #ifndef THINK_C
  164. CWASTEText::CWASTEText()
  165. {
  166.     macWE = NULL;
  167.     spacingCmd = cmdSingleSpace;
  168.     alignCmd = cmdAlignLeft;
  169.  
  170.     selectable = true;
  171.  
  172.     wholeLines = false;
  173.     
  174.     fixedLineHeights = false;
  175.     
  176.     cFirstTaskIndex = 1;  // so we get undo strings
  177.     
  178.     TCL_END_CONSTRUCTOR
  179. }
  180.  
  181. /********************************************************\
  182.  CWASTEText - constructor
  183.      You cannot call IWASTEText if you use this
  184. \********************************************************/
  185.  
  186. CWASTEText::CWASTEText(
  187.     CView            *anEnclosure,
  188.     CBureaucrat        *aSupervisor,
  189.     short            aWidth,
  190.     short            aHeight,
  191.     short            aHEncl,
  192.     short            aVEncl,
  193.     SizingOption    aHSizing,
  194.     SizingOption    aVSizing,
  195.     short            aLineWidth,
  196.     Boolean            aScrollHoriz,
  197.     TextStyle         *tStyle,
  198.     Boolean            supportObjects,
  199.     Boolean            supportUndo,
  200.     Boolean            supportDragAndDrop,
  201.     Boolean            outlineHighliting,
  202.     Boolean            drawOffscreen)
  203.  
  204.     :    CAbstractText(anEnclosure, aSupervisor,
  205.                      aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing,
  206.                      aLineWidth, aScrollHoriz)
  207. {
  208.     macWE = NULL;
  209.     spacingCmd = cmdSingleSpace;
  210.     alignCmd = cmdAlignLeft;
  211.  
  212.     wholeLines = false;
  213.     fixedLineHeights = false;
  214.     selectable = true;
  215.  
  216.     SetPort(macPort);
  217.  
  218.     if (tStyle)
  219.     {
  220.         TextFont(tStyle->tsFont);
  221.         TextSize(tStyle->tsSize);
  222.         TextFace(tStyle->tsFace);
  223.         if (gSystem.hasColorQD)
  224.             RGBForeColor(&tStyle->tsColor);
  225.     }
  226.  
  227.     
  228.     IWASTETextX(supportObjects, supportUndo, supportDragAndDrop, outlineHighliting,
  229.         drawOffscreen);
  230.  
  231.     cFirstTaskIndex = 1;  // so we get undo strings
  232.     
  233.     TCL_END_CONSTRUCTOR
  234. }
  235. #endif // THINK_C
  236.  
  237. /********************************************************\
  238.  ~CWASTEText - destructor
  239. \********************************************************/
  240.  
  241. #ifndef THINK_C
  242. CWASTEText::~CWASTEText()
  243. #else
  244. void CWASTEText::Dispose()
  245. #endif // THINK_C
  246. {
  247.  
  248. #if (TCL_VERSION) >= 0x02000000
  249.     TCL_START_DESTRUCTOR
  250. #endif
  251.  
  252.     if (macWE)
  253.     {
  254.         WEDispose(macWE);
  255.         macWE = NULL;
  256. #if WASTE_VERSION >= 0x01100000
  257.         RemoveDragHandlers();
  258. #endif
  259.     }
  260.     
  261. #ifdef THINK_C
  262.     CAbstractText::Dispose();
  263. #endif
  264.  
  265. }
  266.  
  267. /********************************************************\
  268.  IWASTEText - initialize CWASTEText
  269.      Use this only if you use the default constructor
  270. \********************************************************/
  271.  
  272. void CWASTEText::IWASTEText(
  273.     CView            *anEnclosure,
  274.     CBureaucrat        *aSupervisor,
  275.     short            aWidth,
  276.     short            aHeight,
  277.     short            aHEncl,
  278.     short            aVEncl,
  279.     SizingOption    aHSizing,
  280.     SizingOption    aVSizing,
  281.     short            aLineWidth,
  282.     TextStyle         *tStyle,
  283.     Boolean            supportObjects,
  284.     Boolean            supportUndo,
  285.     Boolean            supportDragAndDrop,
  286.     Boolean            outlineHighliting,
  287.     Boolean            drawOffscreen)
  288. {
  289.  
  290. #ifdef THINK_C
  291.     macWE = NULL;
  292.     spacingCmd = cmdSingleSpace;
  293.     alignCmd = cmdAlignLeft;
  294.  
  295.     wholeLines = false;
  296.     
  297.     fixedLineHeights = false;
  298.     
  299.     cFirstTaskIndex = 1;  // so we get undo strings
  300. #endif // THINK_C
  301.  
  302.     CAbstractText::IAbstractText(anEnclosure, aSupervisor,
  303.                      aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing,
  304.                      aLineWidth);
  305.     if (tStyle)
  306.     {
  307.         TextFont(tStyle->tsFont);
  308.         TextSize(tStyle->tsSize);
  309.         TextFace(tStyle->tsFace);
  310.         if (gSystem.hasColorQD)
  311.             RGBForeColor(&tStyle->tsColor);
  312.     }
  313.  
  314.     IWASTETextX(supportObjects, supportUndo, supportDragAndDrop, outlineHighliting, drawOffscreen);
  315. }
  316.  
  317. /********************************************************\
  318.  IViewTemp - initialize from View resource
  319. \********************************************************/
  320.  
  321. void CWASTEText::IViewTemp(CView *anEnclosure, CBureaucrat *aSupervisor,
  322.                         Ptr viewData)
  323. {
  324.     CAbstractText::IViewTemp(anEnclosure, aSupervisor, viewData);
  325.  
  326.     macWE = NULL;
  327.     spacingCmd = cmdSingleSpace;
  328.     alignCmd = cmdAlignLeft;
  329.     fixedLineHeights = FALSE;
  330.  
  331.     IWASTETextX(true, true, true, true, false); // maybe these features could be added to 
  332.                                                 // a new resource type...
  333. }
  334.  
  335. /********************************************************\
  336.  IWASTETextX - initialization common to above routines
  337. \********************************************************/
  338.  
  339. void CWASTEText::IWASTETextX(Boolean supportObjects, Boolean supportUndo,
  340.     Boolean supportDragAndDrop, Boolean outlineHighliting, Boolean drawOffscreen)
  341. {
  342.     LongRect            tLongFrame;
  343.     Boolean                saveAllocState;
  344.     OSErr                err;
  345.     long                flags;
  346.     void                *thisP; // pointer to this
  347. #if WASTE_VERSION >= 0x01100000
  348.     static WEClickLoopUPP        clickLoop = NULL;
  349.     static WETSMPreUpdateUPP    preProc = NULL;
  350.     static WETSMPostUpdateUPP    postProc = NULL;
  351. #if !WASTE_OBJECT_ARCHIVE
  352.     static WENewObjectUPP        newPICTUPP = NULL;
  353.     static WEDisposeObjectUPP    disposePICTUPP = NULL;
  354.     static WEDrawObjectUPP        drawPICTUPP = NULL;
  355.     static WENewObjectUPP        newSndUPP = NULL;
  356.     static WEDisposeObjectUPP    disposeSndUPP = NULL;
  357.     static WEDrawObjectUPP        drawSndUPP = NULL;
  358.     static WEClickObjectUPP        clickSndUPP = NULL;
  359. #endif
  360. #else
  361.     WEClickLoopProcPtr    clickLoop;
  362.     WETSMPreUpdateProcPtr preProc;
  363.     WETSMPostUpdateProcPtr postProc;
  364. #endif
  365.  
  366. #if (TCL_VERSION) < 0x02000000
  367.     WEReference    theWERef;
  368. #endif
  369.  
  370. #if WASTE_VERSION >= 0x01100000
  371.     dragHandlersInstalled = false;
  372.     hasUndoSupport = supportUndo;
  373. #endif
  374.  
  375.     textMargin = 0;
  376.  
  377.     ForceNextPrepare();
  378.  
  379.     UseLongCoordinates(TRUE);
  380.  
  381.     // Figure out size of of rectangle
  382.     GetAperture(&tLongFrame);
  383.  
  384.     // create WEHandle
  385.     saveAllocState = SetAllocation(kAllocCanFail);
  386.     
  387.     flags = (supportUndo ? weDoUndo : 0) |
  388.             (supportDragAndDrop ? weDoDragAndDrop : 0) |
  389.             (outlineHighliting ? weDoOutlineHilite : 0) |
  390.             (drawOffscreen ? weDoDrawOffscreen : 0); 
  391.             
  392. #if (TCL_VERSION) < 0x02000000
  393.     err = WENew(&tLongFrame, &tLongFrame, flags, &theWERef);
  394.     macWE = theWERef;
  395. #else
  396.     err = WENew(&tLongFrame, &tLongFrame, flags, &macWE);
  397. #endif
  398.  
  399.     SetAllocation(saveAllocState);
  400.     FailOSErr(err);
  401.  
  402.     // set the refcon to this
  403.     thisP = (void *)this;
  404.     WESetInfo(weRefCon, &thisP, macWE);
  405.  
  406.     SetWholeLines(wholeLines);
  407.  
  408.     AdjustBounds();
  409.  
  410.     autoRefresh = lineWidth <= 0;
  411.  
  412.     // •• Install handlers ••
  413. #if WASTE_VERSION >= 0x01100000
  414.     // if first time, make UPP's
  415.     if (clickLoop == NULL)
  416.     {
  417.         clickLoop = NewWEClickLoopProc(WEClickLoop);
  418.         preProc = NewWETSMPreUpdateProc(WEPreUpdate);
  419.         postProc = NewWETSMPostUpdateProc(WEPostUpdate);
  420.     }
  421. #else
  422.     preProc = &WEPreUpdate;
  423.     postProc = &WEPostUpdate;
  424.     clickLoop = &WEClickLoop;
  425. #endif
  426.  
  427.     WESetInfo(weTSMPreUpdate, (Ptr)&preProc, macWE);
  428.     WESetInfo(weTSMPostUpdate, (Ptr)&postProc, macWE);
  429.     WESetInfo(weClickLoop, (Ptr)&clickLoop, macWE);
  430.  
  431.     CalcWERects();
  432.     if (lineWidth < 0)
  433.     {
  434.         saveAllocState = SetAllocation(kAllocCanFail);
  435.         err = WECalText(macWE);
  436.         SetAllocation(saveAllocState);
  437.     }
  438.  
  439. #if WASTE_TABS
  440. #if WASTE_AUTO_TABS
  441.     InstallTabHandlers();
  442. #endif // WASTE_AUTO_TABS
  443. #endif // WASTE_TABS
  444.  
  445. #if WASTE_VERSION >= 0x01100000
  446.  
  447.     hasObjectSupport = supportObjects;
  448.     if (supportObjects)
  449.     {
  450. #if WASTE_OBJECT_ARCHIVE
  451.         FailOSErr(InstallAllWASTEObjHandlers(NULL));
  452. #else
  453. #if WASTE_OBJECTS
  454.         if (newPICTUPP == NULL)
  455.         {
  456.             newPICTUPP = NewWENewObjectProc(HandleNewPicture);
  457.             disposePICTUPP = NewWEDisposeObjectProc(HandleDisposePicture);
  458.             drawPICTUPP = NewWEDrawObjectProc(HandleDrawPicture);
  459.         
  460.             newSndUPP = NewWENewObjectProc(HandleNewSound);
  461.             disposeSndUPP = NewWEDisposeObjectProc(HandleDisposeSound);
  462.             drawSndUPP = NewWEDrawObjectProc(HandleDrawSound);
  463.             clickSndUPP = NewWEClickObjectProc(HandleClickSound);
  464.         }
  465.         
  466.         // •• Install Picture Handlers ••
  467.         FailOSErr(WEInstallObjectHandler(kTypePicture, weNewHandler, (UniversalProcPtr)newPICTUPP, NULL));
  468.         FailOSErr(WEInstallObjectHandler(kTypePicture, weDisposeHandler, (UniversalProcPtr)disposePICTUPP, NULL));
  469.         FailOSErr(WEInstallObjectHandler(kTypePicture, weDrawHandler, (UniversalProcPtr)drawPICTUPP, NULL));
  470.     
  471.         // •• Install Sound Handlers ••
  472.         FailOSErr(WEInstallObjectHandler(kTypeSound, weNewHandler, (UniversalProcPtr)newSndUPP, NULL));
  473.         FailOSErr(WEInstallObjectHandler(kTypeSound, weDisposeHandler, (UniversalProcPtr)disposeSndUPP, NULL));
  474.         FailOSErr(WEInstallObjectHandler(kTypeSound, weDrawHandler, (UniversalProcPtr)drawSndUPP, NULL));
  475.         FailOSErr(WEInstallObjectHandler(kTypeSound, weClickHandler, (UniversalProcPtr)clickSndUPP, NULL));
  476. #endif // WASTE_OBJECTS
  477. #endif // WASTE_OBJECT_ARCHIVE
  478.  
  479.     }
  480. #endif // WASTE 1.1
  481. }
  482.  
  483. #if WASTE_TABS
  484. /********************************************************\
  485.  InstallTabHandlers -- with WASTE 1.1 or later, will
  486.      install the hooks to support tabs in WASTE.  If
  487.      WASTE_AUTO_TABS, this will be called for you.
  488.      Newest version of WEInstallTabHooks returns an OSErr
  489.      but we'll ignore it for compatibility with the older
  490.      version
  491. \********************************************************/
  492.  
  493. void CWASTEText::InstallTabHandlers(void)
  494. {
  495.     WEInstallTabHooks(macWE);
  496. }
  497. #endif
  498.  
  499. /********************************************************\
  500.  SetTextMargin -- set a margin that will be left between
  501.     the destRect and viewRect in WASTE
  502. \********************************************************/
  503.  
  504. void CWASTEText::SetTextMargin(short margin)
  505. {
  506.     textMargin = margin;
  507.     CalcWERects();
  508.     AdjustBounds();
  509. }
  510.  
  511. #if WASTE_VERSION >= 0x01100000
  512. /********************************************************\
  513.  WASTETrackingHandler - handles drag tracking
  514. \********************************************************/
  515.  
  516. pascal OSErr WASTETrackingHandler(DragTrackingMessage theMessage, WindowPtr theWindow,
  517.     void *handlerRefCon, DragReference theDrag)
  518. {
  519.     if (theWindow!=NULL)
  520.     {
  521.         ((CWASTEText *)handlerRefCon)->Prepare();
  522.         ClipRect(&theWindow->portRect);
  523.         return WETrackDrag(theMessage, theDrag, ((CWASTEText *)handlerRefCon)->macWE);    
  524.     }
  525.     else
  526.     {
  527.         return noErr;
  528.     }
  529. }
  530.  
  531. /********************************************************\
  532.  WASTEReceiveHandler - handles receiving a drag
  533. \********************************************************/
  534.  
  535. pascal OSErr WASTEReceiveHandler(WindowPtr theWindow, void *handlerRefCon, DragReference theDrag)
  536. {
  537.     OSErr err = noErr;
  538.     CWASTETask *wasteTask;
  539.     
  540.     if (theWindow!=NULL)
  541.     {
  542.         ((CWASTEText *)handlerRefCon)->Prepare();
  543.         ClipRect(&theWindow->portRect);
  544.         err = WEReceiveDrag(theDrag, ((CWASTEText *)handlerRefCon)->macWE);    
  545.         ((CWASTEText *)handlerRefCon)->AdjustBounds();
  546.         if (((CWASTEText *)handlerRefCon)->hasUndoSupport)
  547.         {
  548. #if (TCL_VERSION) >= 0x02000000
  549.             wasteTask = new CWASTETask((CWASTEText *)handlerRefCon);
  550. #else
  551.             wasteTask = new (CWASTETask);
  552.             wasteTask->IWASTETask((CWASTEText *)handlerRefCon);
  553. #endif
  554.             ((CWASTEText *)handlerRefCon)->itsSupervisor->Notify(wasteTask);
  555.         }
  556.     }
  557.     return err;
  558. }
  559.  
  560. #if WASTE_OBJECTS && !WASTE_OBJECT_ARCHIVE
  561.  
  562. /********************************************************\
  563.  HandleNewPicture - Handler for creating pictures
  564.      from WASTE Demo source
  565. \********************************************************/
  566.  
  567. pascal OSErr HandleNewPicture(Point *defaultObjectSize, WEObjectReference objectRef)
  568. {
  569.     PicHandle thePicture;
  570.     Rect frame;
  571.  
  572.     // { get handle to object data (in this case, a picture handle) }
  573.     thePicture = (PicHandle)WEGetObjectDataHandle(objectRef);
  574.  
  575.     // { figure out the default object size by looking at the picFrame record }
  576.     frame = (*thePicture)->picFrame;
  577.     OffsetRect(&frame, -frame.left, -frame.top);
  578.     defaultObjectSize->h = frame.right;
  579.     defaultObjectSize->v = frame.bottom;
  580.  
  581.     return noErr;
  582. }
  583.  
  584. /********************************************************\
  585.  HandleDisposePicture - handles disposing a picture
  586.      From WASTE Demo source
  587. \********************************************************/
  588.  
  589. pascal OSErr HandleDisposePicture(WEObjectReference objectRef)
  590. {
  591.     PicHandle thePicture;
  592.  
  593.     // { get handle to object data (in this case, a picture handle) }
  594.     thePicture = (PicHandle)WEGetObjectDataHandle(objectRef);
  595.  
  596.     // { kill the picture }
  597.     KillPicture(thePicture);
  598.  
  599.     return MemError();
  600. }
  601.  
  602. /********************************************************\
  603.  HandleDrawPicture - handle drawing a picture
  604.      From WASTE Demo source
  605. \********************************************************/
  606.  
  607. pascal OSErr HandleDrawPicture(Rect *destRect, WEObjectReference objectRef)
  608. {
  609.     PicHandle thePicture;
  610.  
  611.     // { get handle to object data (in this case, a picture handle) }
  612.     thePicture = (PicHandle)WEGetObjectDataHandle(objectRef);
  613.  
  614.     // { draw the picture }
  615.     DrawPicture(thePicture, destRect);
  616.  
  617.     return noErr;
  618. }
  619.  
  620. /********************************************************\
  621.  HandleNewSound - Handler for creating sounds
  622. \********************************************************/
  623.  
  624. pascal OSErr HandleNewSound(Point *defaultObjectSize, WEObjectReference objectRef)
  625. {
  626.     // icon is 32x32
  627.  
  628.     defaultObjectSize->h = 32;
  629.     defaultObjectSize->v = 32;
  630.  
  631.     return noErr;
  632. }
  633.  
  634. /********************************************************\
  635.  HandleDisposeSound - handles disposing a sound
  636. \********************************************************/
  637.  
  638. pascal OSErr HandleDisposeSound(WEObjectReference objectRef)
  639. {
  640.     Handle theSound;
  641.  
  642.     // { get handle to object data (in this case, a sound handle) }
  643.     theSound = WEGetObjectDataHandle(objectRef);
  644.  
  645.     DisposeHandle(theSound);
  646.  
  647.     return MemError();
  648. }
  649.  
  650. /********************************************************\
  651.  HandleClickSound - handle clicking a sound (play it)
  652. \********************************************************/
  653.  
  654. pascal OSErr HandleClickSound(Point hitPt, short modifiers, long clickTime,
  655.     WEObjectReference objectRef)
  656. {
  657.     OSErr err;
  658.     Handle theSound;
  659.  
  660.     // { get handle to object data (in this case, a sound handle) }
  661.     theSound = WEGetObjectDataHandle(objectRef);
  662.  
  663.     // the following is an attempt to check for Universal Headers 2.0
  664. #if !defined(GENERATINGPOWERPC) && !defined(GENERATING68K)
  665.     err = SndPlay(NULL, theSound, false);
  666. #else
  667.     err = SndPlay(NULL, (SndListHandle)theSound, false);
  668. #endif
  669.  
  670.     return err;
  671. }
  672.  
  673. /********************************************************\
  674.  HandleDrawSound -- draw an icon for the sound
  675. \********************************************************/
  676.  
  677. pascal OSErr HandleDrawSound(Rect *destRect, WEObjectReference objectRef)
  678. {
  679.     PlotIconID(destRect, atNone, ttNone, kSoundIconNumber);
  680.     return noErr;
  681. }
  682.  
  683. #endif // WASTE_OBJECTS && !WASTE_OBJECT_ARCHIVE
  684.  
  685. /********************************************************\
  686.  InstallDragHandlers - installs the handlers for
  687.      receiving drags.
  688.      Note: This can only be called for one CWASTEText
  689.      instance per window
  690. \********************************************************/
  691.  
  692. void CWASTEText::InstallDragHandlers(void)
  693. {
  694.     WindowPtr dragWindow = GetWindow()->macPort;
  695.  
  696.     if (gHasDragAndDrop && !dragHandlersInstalled)
  697.     {
  698.         if (trackingUPP == NULL) // need to create UPP
  699.         {
  700.             trackingUPP = NewDragTrackingHandlerProc(WASTETrackingHandler);
  701.         }
  702.         FailOSErr(InstallTrackingHandler(trackingUPP, dragWindow, this));
  703.  
  704.         if (receiveUPP == NULL) // need to create UPP
  705.         {
  706.             receiveUPP = NewDragReceiveHandlerProc(WASTEReceiveHandler);
  707.         }
  708.         FailOSErr(InstallReceiveHandler(receiveUPP, dragWindow, this));
  709.  
  710.         dragHandlersInstalled = true;
  711.     }
  712. }
  713.  
  714. /********************************************************\
  715.  RemoveDragHandlers -- removes the drag handlers
  716. \********************************************************/
  717.  
  718. void CWASTEText::RemoveDragHandlers(void)
  719. {
  720.     WindowPtr dragWindow = GetWindow()->macPort;
  721.  
  722.     if (gHasDragAndDrop && dragHandlersInstalled)
  723.     {
  724.         FailOSErr(RemoveTrackingHandler(trackingUPP, dragWindow));
  725.         FailOSErr(RemoveReceiveHandler(receiveUPP, dragWindow));
  726.         dragHandlersInstalled = false;
  727.     }
  728. }
  729. #endif // WASTE 1.1
  730.  
  731. /********************************************************\
  732.  CheckInsertion - sees if the specified amount of text
  733.      can be inserted
  734. \********************************************************/
  735.  
  736. void CWASTEText::CheckInsertion(long numChars, long styleSize, Boolean useSelection)
  737. {
  738.     long    selStart, selEnd;
  739.     long    growSize = numChars;
  740.     Handle    h;
  741.     OSErr    err;
  742.  
  743.     if (useSelection)
  744.     {
  745.         GetSelection(&selStart, &selEnd);
  746.         growSize -= TCLAbs(selEnd - selStart);
  747.     }
  748.  
  749.     /*    The problem with WASTE is that it can succeed in adding the text to its content
  750.      *    structure, and then fail to expand its style tables or line start tables.  The way
  751.      *    I address this is to add a fudge factor to the amount of data being added, and
  752.      *    hope that its enough to cover the WASTE overhead.
  753.      */
  754.  
  755.     if (growSize > 0)
  756.     {
  757.         /*    Add fudge factor for new line starts (1/5th of numChars)    */
  758.         
  759.         growSize += growSize / 5;
  760.         
  761.         /*    Add fudge factor for style information (1/2 of styleSize)    */
  762.  
  763.         growSize += styleSize + styleSize / 2;
  764.  
  765.         if (WEFeatureFlag(weFUseTempMem, weBitTest, macWE))
  766.         {
  767.             h = TempNewHandle(growSize, &err);
  768.             if (!h && err == noErr)
  769.                 err = memFullErr;
  770.             DisposeHandle(h);
  771.             FailOSErr(err);
  772.         }
  773.         else
  774.         {
  775.             h = NewHandleCanFail(growSize);
  776.             FailNIL(h);
  777.             DisposeHandle(h);
  778.         }
  779.     }
  780. }
  781.  
  782. #if WASTE_VERSION >= 0x01100000
  783. static long sOldModCount = -1; // for keeping track of modifications by inline input
  784. #endif
  785.  
  786. /********************************************************\
  787.  WEPreUpdate -- prepare the port
  788. \********************************************************/
  789.  
  790. pascal void CWASTEText::WEPreUpdate(WEHandle hWE)
  791. {
  792.     CWASTEText *itsOwner = NULL;
  793.  
  794.     WEGetInfo(weRefCon, (Ptr)&itsOwner, hWE);
  795. #if (TCL_VERSION) >= 0x02000000
  796.     TCL_ASSERT_OBJECT_PTR(itsOwner);
  797.     TCL_ASSERT(member(itsOwner, CWASTEText));
  798. #else
  799.     ASSERT(member(itsOwner, CWASTEText));
  800. #endif
  801.     
  802.     if (itsOwner != NULL)
  803.     {
  804. #if WASTE_VERSION >= 0x01100000
  805.         sOldModCount = WEGetModCount(hWE);
  806. #endif
  807.         itsOwner->Prepare();
  808.     }
  809. }
  810.  
  811. /********************************************************\
  812.  WEPostUpdate -- keep typing visible -- by M. Sladok
  813. \********************************************************/
  814.  
  815. pascal void CWASTEText::WEPostUpdate(WEHandle hWE, long fixLength, long inputAreaStart,
  816.     long inputAreaEnd, long pinRangeStart, long pinRangeEnd)
  817. {
  818. #if WASTE_VERSION >= 0x01100000
  819.     long newModCount;
  820.     CWASTETask *wasteTask;
  821. #endif
  822.     CWASTEText *itsOwner = NULL;
  823.  
  824.     WEGetInfo(weRefCon, (Ptr)&itsOwner, hWE);
  825. #if (TCL_VERSION) >= 0x02000000
  826.     TCL_ASSERT_OBJECT_PTR(itsOwner);
  827.     TCL_ASSERT(member(itsOwner, CWASTEText));
  828. #else
  829.     ASSERT(member(itsOwner, CWASTEText));
  830. #endif
  831.     
  832.     if (itsOwner != NULL)
  833.     {
  834.         itsOwner->AdjustBounds();
  835.         itsOwner->ScrollToRange(pinRangeStart, pinRangeEnd); // modified in WASTE TCL 2.0
  836. #if WASTE_VERSION >= 0x01100000
  837.         newModCount = WEGetModCount(hWE);
  838.         if (itsOwner->hasUndoSupport && newModCount != sOldModCount) // inline input occured
  839.         {
  840. #if (TCL_VERSION) >= 0x02000000
  841.             wasteTask = new CWASTETask(itsOwner);
  842. #else
  843.             wasteTask = new (CWASTETask);
  844.             wasteTask->IWASTETask(itsOwner);
  845. #endif
  846.             itsOwner->itsSupervisor->Notify(wasteTask);
  847.         }
  848. #endif
  849.     }
  850. }
  851.  
  852. /********************************************************\
  853.  DoClick - handle mouse clicks
  854. \********************************************************/
  855.  
  856. void CWASTEText::DoClick(Point hitPt, short modifierKeys, long when)
  857. {
  858. #if WASTE_VERSION >= 0x01100000
  859.     long oldModCount, newModCount;
  860.     CWASTETask *wasteTask;
  861.  
  862.     if (!wantsClicks) return;
  863.     if (!selectable) return; // added WASTE TCL 2.0
  864.     
  865.     oldModCount = WEGetModCount(macWE);
  866. #endif
  867.  
  868.     WEClick(hitPt, modifierKeys, when, macWE);
  869. #if WASTE_VERSION >= 0x01100000
  870.     newModCount = WEGetModCount(macWE);
  871. #endif
  872.     
  873.         // CSwitchboard will never see the mouse up that ended
  874.         // the drag, so we stuff gLastMouseUp here to allow
  875.         // multi-click counting to work.
  876.         
  877.     gLastMouseUp.what = mouseUp;
  878.     gLastMouseUp.when = TickCount();
  879.     gLastMouseUp.where = hitPt;
  880.     LocalToGlobal( &gLastMouseUp.where);
  881.     gLastMouseUp.modifiers = modifierKeys;
  882.  
  883.     SelectionChanged();
  884.     
  885.     // make task if a drag occured (so it can be undone)
  886. #if WASTE_VERSION >= 0x01100000
  887.     if (hasUndoSupport && oldModCount != newModCount) // drag occured
  888.     {
  889. #if (TCL_VERSION) >= 0x02000000
  890.         wasteTask = new CWASTETask(this);
  891. #else
  892.         wasteTask = new (CWASTETask);
  893.         wasteTask->IWASTETask(this);
  894. #endif
  895.         itsSupervisor->Notify(wasteTask);
  896.     }
  897. #endif
  898. #if WASTE_VERSION == 0x01000000
  899.     if (!editable && (gGopher == this))
  900.     {
  901.         long selStart, selEnd;
  902.         
  903.         GetSelection( &selStart, &selEnd);    
  904.         if (selStart == selEnd)
  905.             itsSupervisor->BecomeGopher( TRUE);
  906.     }
  907. #endif
  908. }
  909.  
  910. #if WASTE_VERSION >= 0x01100000
  911.  
  912. /******************************************************************************
  913.  DoKeyDown - handles key strokes and the undoing of them
  914.      This version is for WASTE 1.1 or higher
  915.  ******************************************************************************/
  916.  
  917. void CWASTEText::DoKeyDown(char theChar, Byte keyCode, EventRecord *macEvent)
  918. {
  919.     CWASTETask *wasteTask;
  920.  
  921.     // Don't try to insert and command keys into the text,
  922.     // pass them along the command chain
  923.  
  924.     if (macEvent->modifiers & cmdKey)
  925.     {
  926.         inherited::DoKeyDown(theChar, keyCode, macEvent);
  927.         return;
  928.     }
  929.  
  930.     switch (keyCode)
  931.     {
  932.  
  933.         case KeyHome:
  934.         case KeyPageUp:
  935.         case KeyPageDown:
  936.         case KeyEnd:
  937.         case KeyLeftCursor:
  938.         case KeyRightCursor:
  939.         case KeyUpCursor:
  940.         case KeyDownCursor:
  941.             inherited::DoKeyDown(theChar, keyCode, macEvent);
  942.             break;
  943.  
  944.         default:
  945.             if (editable)
  946.             {
  947.                 Boolean wasTyping = WEIsTyping(macWE);
  948.                 
  949.                 TypeChar(theChar, macEvent->modifiers);
  950.                 if (hasUndoSupport && !wasTyping)
  951.                 {
  952. #if (TCL_VERSION) >= 0x02000000
  953.                     wasteTask = new CWASTETask(this);
  954. #else
  955.                     wasteTask = new (CWASTETask);
  956.                     wasteTask->IWASTETask(this);
  957. #endif
  958.                     itsSupervisor->Notify(wasteTask);
  959.                 }
  960. #if (TCL_VERSION) >= 0x02000000
  961.                 SetChanged(true); // tell supervisor that we've changed
  962.                                   // TCL <2 doesn't have this command
  963. #endif
  964.             }
  965.             break;
  966.     }
  967. }
  968.  
  969. /********************************************************\
  970.  DoCommand - version that uses WASTE 1.1's undo features
  971. \********************************************************/
  972.  
  973. void CWASTEText::DoCommand(long theCommand)
  974. {
  975.     CWASTETask *wasteTask;
  976.     Boolean makeTask = false;
  977.     Str255            itemName;
  978.     long            number;
  979.  
  980.     if (theCommand < 0)
  981.     {
  982. #if (TCL_VERSION) >= 0x02000000
  983.         switch (TCLHiShort(-theCommand))
  984. #else
  985.         switch (HiShort(-theCommand))
  986. #endif
  987.         {
  988.             // •• font menu ••
  989.             case MENUfont:
  990.                 gBartender->GetCmdText(theCommand, itemName);
  991.                 SetFontName(itemName);
  992.                 makeTask = true;
  993.                 break;
  994.             
  995.             // •• Size menu ••
  996.             case MENUsize:
  997.                 gBartender->GetCmdText(theCommand, itemName);
  998.                 StringToNum(itemName, &number);
  999.                 SetFontSize(number);
  1000.                 makeTask = true;
  1001.                 break;
  1002.  
  1003.             default:
  1004.                 CPanorama::DoCommand(theCommand);
  1005.                 break;
  1006.         }
  1007.  
  1008.     }
  1009.     else
  1010.     {
  1011.         switch (theCommand)
  1012.         {
  1013.             case cmdCut:
  1014.             case cmdPaste:
  1015.             case cmdClear:
  1016.                 if (!editable)
  1017.                 {
  1018.                     SysBeep(3);
  1019.                     break;
  1020.                 }
  1021.                 PerformEditCommand(theCommand);
  1022.                 makeTask = true;
  1023.                 break;
  1024.  
  1025.             case cmdCopy:
  1026.                 PerformEditCommand(theCommand);
  1027.                 break;
  1028.  
  1029.             case cmdSelectAll:
  1030.                 Prepare();
  1031.                 SelectAll(TRUE);
  1032.                 SelectionChanged();
  1033.                 break;
  1034.  
  1035.             case cmdPlain:
  1036.                 SetFontStyle(NOTHING);
  1037.                 makeTask = true;
  1038.                 break;
  1039.  
  1040.             case cmdBold:                    // Styles are set by flipping bits
  1041.             case cmdItalic:                    //   Bold is bit 0, Italic is bit 1
  1042.             case cmdUnderline:                //   Underline is bit 2, etc.
  1043.             case cmdOutline:                //   By cleverly numbering these
  1044.             case cmdShadow:                    //   commands, we can just shift
  1045.             case cmdCondense:                //   a bit to get the proper style
  1046.             case cmdExtend:
  1047.                 SetFontStyle(1 << (theCommand - cmdBold));
  1048.                 makeTask = true;
  1049.                 break;
  1050.  
  1051.             case cmdBlack:
  1052.                     SetFontColor(&RGBBlack);
  1053.                     makeTask = true;
  1054.                     break;
  1055.             case cmdRed:
  1056.                     SetFontColor(&RGBRed);
  1057.                     makeTask = true;
  1058.                     break;
  1059.             case cmdGreen:
  1060.                     SetFontColor(&RGBGreen);
  1061.                     makeTask = true;
  1062.                     break;
  1063.             case cmdBlue:
  1064.                     SetFontColor(&RGBBlue);
  1065.                     makeTask = true;
  1066.                     break;
  1067.             case cmdCyan:
  1068.                     SetFontColor(&RGBCyan);
  1069.                     makeTask = true;
  1070.                     break;
  1071.             case cmdMagenta:
  1072.                     SetFontColor(&RGBMagenta);
  1073.                     makeTask = true;
  1074.                     break;
  1075.             case cmdYellow:
  1076.                     SetFontColor(&RGBYellow);
  1077.                     makeTask = true;
  1078.                     break;
  1079.  
  1080.             case cmdAlignLeft:
  1081.             case cmdAlignCenter:
  1082.             case cmdAlignRight:
  1083.             case cmdJustify:
  1084.                 SetAlignCmd(theCommand);
  1085.                 // not undoable at this time
  1086.                 break;
  1087.  
  1088.             case cmdSingleSpace:
  1089.             case cmd1HalfSpace:
  1090.             case cmdDoubleSpace:
  1091.                 SetSpacingCmd(theCommand);
  1092.                 // not undoable at this time
  1093.                 break;
  1094.  
  1095.             default:
  1096.                 CPanorama::DoCommand(theCommand);
  1097.                 break;
  1098.         }
  1099.     }
  1100.     
  1101.     if (makeTask && hasUndoSupport)
  1102.     {
  1103. #if (TCL_VERSION) >= 0x02000000
  1104.         wasteTask = new CWASTETask(this);
  1105. #else
  1106.         wasteTask = new (CWASTETask);
  1107.         wasteTask->IWASTETask(this);
  1108. #endif
  1109.         itsSupervisor->Notify(wasteTask);
  1110.     }
  1111. }
  1112.  
  1113. #else // WASTE 1.0
  1114. /********************************************************\
  1115.  DoCommand - AbstractText does not deal with justify so
  1116.      we have to special case it. And color too
  1117.      This version is for WASTE 1.0
  1118. \********************************************************/
  1119.  
  1120. void    CWASTEText::DoCommand(long theCommand)
  1121. {
  1122.     CTextStyleTask    *styleTask = NULL;
  1123.     Boolean        makeStyleTask = FALSE;
  1124.  
  1125.     if (stylable)
  1126.     {
  1127.         switch (theCommand)
  1128.         {
  1129.             case cmdJustify:
  1130.             case cmdBlack:
  1131.             case cmdRed:
  1132.             case cmdBlue:
  1133.             case cmdGreen:
  1134.             case cmdCyan:
  1135.             case cmdMagenta:
  1136.             case cmdYellow:
  1137.                 makeStyleTask =TRUE;
  1138.                 break;
  1139.             default: ;
  1140.         }
  1141.     }
  1142.         
  1143.     if (makeStyleTask)
  1144.     {
  1145.         itsTypingTask = NULL;
  1146.         styleTask = MakeStyleTask(theCommand);
  1147.         itsLastTask = styleTask;
  1148.         itsSupervisor->Notify(styleTask);
  1149.         styleTask->Do();
  1150.     }
  1151.     else
  1152.         inherited::DoCommand(theCommand);
  1153. }
  1154. #endif
  1155.  
  1156. /********************************************************\
  1157.  UpdateMenus - handle WASTE specific menu enabling
  1158. \********************************************************/
  1159.  
  1160. void CWASTEText::UpdateMenus()
  1161. {
  1162.     long    selStart, selEnd;
  1163.     TextStyle        style;
  1164.     short            styleFlags;
  1165.  
  1166.     inherited::UpdateMenus();
  1167.     
  1168.         // Copy and Cut are only possible if the selection is small (< 32K).
  1169.         // The danger here is that a piece of styled text > 32K will pass
  1170.         // through the clipboard to another application which cannot handle
  1171.         // it (like the Finder).
  1172.         //
  1173.         // Should probably override DoCommand as well to make sure a command
  1174.         // does not get past the Menu Manager -- can be done later.
  1175.     
  1176.     GetSelection(&selStart, &selEnd);
  1177.     if (TCLAbs(selEnd - selStart) >= 32767)
  1178.     {
  1179.         gBartender->DisableCmd(cmdCopy);
  1180.         gBartender->DisableCmd(cmdCut);
  1181.     }
  1182. #if WASTE_VERSION >= 0x01100000
  1183.     if (WECanPaste(macWE))
  1184.         gBartender->EnableCmd(cmdPaste);
  1185.     else
  1186.         gBartender->DisableCmd(cmdPaste);
  1187. #endif
  1188.  
  1189.     gBartender->EnableCmd(cmdBlack);
  1190.     gBartender->EnableCmd(cmdRed);
  1191.     gBartender->EnableCmd(cmdGreen);
  1192.     gBartender->EnableCmd(cmdBlue);
  1193.     gBartender->EnableCmd(cmdCyan);
  1194.     gBartender->EnableCmd(cmdMagenta);
  1195.     gBartender->EnableCmd(cmdYellow);
  1196.  
  1197.     // figure out the continuous color
  1198.     styleFlags = doColor;
  1199.     GetTextStyle (&styleFlags,  &style);
  1200.  
  1201.     if (styleFlags & doColor)
  1202.     {
  1203.         if (style.tsColor.red == 0)
  1204.         {
  1205.             if (style.tsColor.green == 0)
  1206.             {
  1207.                 if (style.tsColor.blue == 0)
  1208.                 {
  1209.                     gBartender->CheckMarkCmd(cmdBlack, true);
  1210.                 }
  1211.                 else if (style.tsColor.blue == 65535)
  1212.                 {
  1213.                     gBartender->CheckMarkCmd(cmdBlue, true);
  1214.                 }
  1215.             }
  1216.             else if (style.tsColor.green == 65535)
  1217.             {
  1218.                 if (style.tsColor.blue == 0)
  1219.                 {
  1220.                     gBartender->CheckMarkCmd(cmdGreen, true);
  1221.                 }
  1222.                 else if (style.tsColor.blue == 65535)
  1223.                 {
  1224.                     gBartender->CheckMarkCmd(cmdCyan, true);
  1225.                 }
  1226.             }
  1227.         }
  1228.         else if (style.tsColor.red == 65535)
  1229.         {
  1230.             if (style.tsColor.green == 0)
  1231.             {
  1232.                 if (style.tsColor.blue == 0)
  1233.                 {
  1234.                     gBartender->CheckMarkCmd(cmdRed, true);
  1235.                 }
  1236.                 else if (style.tsColor.blue == 65535)
  1237.                 {
  1238.                     gBartender->CheckMarkCmd(cmdMagenta, true);
  1239.                 }
  1240.             }
  1241.             else if (style.tsColor.green == 65535)
  1242.             {
  1243.                 if (style.tsColor.blue == 0)
  1244.                 {
  1245.                     gBartender->CheckMarkCmd(cmdYellow, true);
  1246.                 }
  1247.                 else if (style.tsColor.blue == 65535)
  1248.                 {
  1249.                     // no white
  1250.                 }
  1251.             }
  1252.         }
  1253.     }
  1254. }
  1255.  
  1256. #if WASTE_VERSION == 0x01000000
  1257. /********************************************************\
  1258.  MakeEditTask -- use WASTE specific one
  1259.      For WASTE 1.0 only
  1260. \********************************************************/
  1261.  
  1262. CTextEditTask *CWASTEText::MakeEditTask( long editCmd)
  1263. {
  1264.     CWASTEEditTask *volatile editTask = NULL;
  1265.     
  1266.     try_
  1267.     {
  1268. #if (TCL_VERSION) >= 0x02000000
  1269.         editTask = new CWASTEEditTask(this, editCmd, cFirstTaskIndex);
  1270. #else
  1271.         editTask = new (CWASTEEditTask);
  1272.         editTask->IWASTEEditTask(this, editCmd, cFirstTaskIndex);
  1273. #endif
  1274.     }
  1275.     catch_all_()
  1276.     {
  1277. #if (TCL_VERSION) >= 0x02000000
  1278.         TCLForgetObject(editTask);
  1279. #else
  1280.         ForgetObject(editTask);
  1281. #endif
  1282.  
  1283.         throw_same_();
  1284.     }
  1285.     end_try_
  1286.     
  1287.     return editTask;
  1288. }
  1289.  
  1290. /********************************************************\
  1291.  MakeStyleTask -- use WASTE specific one
  1292.      WASTE 1.0 only
  1293. \********************************************************/
  1294.  
  1295. CTextStyleTask *CWASTEText::MakeStyleTask( long styleCmd)
  1296. {
  1297.  
  1298.     CWASTEStyleTask *volatile newTask = NULL;
  1299.     short            taskIndex;
  1300.     
  1301.     try_
  1302.     {
  1303.         taskIndex = cFirstTaskIndex > 0 ? cFirstTaskIndex + undoFormatting : 0;
  1304. #if (TCL_VERSION) >= 0x02000000
  1305.         newTask = new CWASTEStyleTask(this, styleCmd, taskIndex);
  1306. #else
  1307.         newTask = new (CWASTEStyleTask);
  1308.         newTask->IWASTEStyleTask(this, styleCmd, taskIndex);
  1309. #endif
  1310.     }
  1311.  
  1312.     catch_all_()
  1313.     {
  1314. #if (TCL_VERSION) >= 0x02000000
  1315.         TCLForgetObject( newTask);
  1316. #else
  1317.         ForgetObject(newTask);
  1318. #endif
  1319.  
  1320.         throw_same_();
  1321.     }
  1322.     end_try_
  1323.     
  1324.     return newTask;
  1325. }
  1326. #endif
  1327.  
  1328. /********************************************************\
  1329.  PerformEditCommand - handle cut, copy, paste, and clear
  1330. \********************************************************/
  1331.  
  1332. void CWASTEText::PerformEditCommand(long theCommand)
  1333. {
  1334.     Boolean        saveAllocState;
  1335.     OSErr        err = noErr;
  1336.  
  1337.     Prepare();
  1338.     if (!ReallyVisible())
  1339.         SetOrigin(-10000, -10000);
  1340.  
  1341.     switch( theCommand)
  1342.     {        
  1343.         case cmdCut:
  1344.             gClipboard->EmptyGlobalScrap();
  1345.             saveAllocState = SetAllocation(kAllocCanFail);        
  1346.             err = WECut(macWE);
  1347.             SetAllocation(saveAllocState);
  1348.             if (err == noErr)
  1349.                 gClipboard->UpdateDisplay();
  1350.             break;
  1351.             
  1352.         case cmdCopy:
  1353.             gClipboard->EmptyGlobalScrap();
  1354.             saveAllocState = SetAllocation(kAllocCanFail);        
  1355.             err = WECopy(macWE);
  1356.             SetAllocation(saveAllocState);
  1357.             if (err == noErr)
  1358.                 gClipboard->UpdateDisplay();
  1359.             break;
  1360.             
  1361.         case cmdPaste:
  1362.             // note: doesn't check the soup...
  1363.             CheckInsertion(gClipboard->DataSize('TEXT'),
  1364.                            gClipboard->DataSize('styl'), TRUE);
  1365.             saveAllocState = SetAllocation(kAllocCanFail);
  1366. #if WASTE_OBJECT_ARCHIVE
  1367.             err = WEObjectsPaste(macWE);
  1368. #else
  1369.             err = WEPaste(macWE);
  1370. #endif
  1371.             SetAllocation(saveAllocState);
  1372.             break;
  1373.             
  1374.         case cmdClear:
  1375.             saveAllocState = SetAllocation(kAllocCanFail);        
  1376.             err = WEDelete(macWE);
  1377.             SetAllocation(saveAllocState);
  1378.             break;
  1379.             
  1380.     }
  1381.     AdjustBounds();
  1382.     ScrollToSelection();
  1383.     FailOSErr(err);
  1384. }
  1385.  
  1386.  
  1387. /********************************************************\
  1388.  Draw - draw the text
  1389. \********************************************************/
  1390.  
  1391. void CWASTEText::Draw(Rect *area)
  1392. {
  1393.     RgnHandle    updateRgn;
  1394.     LongRect    fr, dr;
  1395.     Rect        r;
  1396.     short        oldOffscreen, oldOutline;
  1397.     OSErr        err;
  1398.     
  1399.     if (!ReallyVisible())
  1400.         return;
  1401.  
  1402.     updateRgn = NewRgn();
  1403.     RectRgn(updateRgn, area);
  1404.     
  1405.     if (!printing)
  1406.     {
  1407.         SectRgn(updateRgn, macPort->visRgn, updateRgn);
  1408.         CalcWERects();
  1409.     }
  1410.     else
  1411.     {
  1412.         err = WESetInfo(wePort, (Ptr)&qd.thePort, macWE);
  1413.         // temporarily turn off off screen drawing and outline hiliting
  1414.         oldOffscreen = WEFeatureFlag(weFDrawOffscreen, weBitClear, macWE);
  1415.         oldOutline = WEFeatureFlag(weFOutlineHilite, weBitClear, macWE);
  1416.  
  1417.         // Prepare the destination and view rectangles
  1418.  
  1419.         WEGetDestRect(&dr, macWE);
  1420.         GetAperture(&fr);
  1421.         OffsetLongRect(&dr, -(dr.left + fr.left), -(dr.top + fr.top));
  1422.         FrameToQDR(&fr, &r);
  1423.         OffsetLongRect(&dr, r.left, r.top);
  1424.         dr.right = (lineWidth > 0) ? dr.left + lineWidth : printPageWidth;
  1425.         WESetDestRect(&dr, macWE);
  1426.         QDToLongRect(area, &fr);
  1427.         if (wholeLines)
  1428.             fr.bottom = fr.top + vScale * ((area->bottom - area->top) / vScale);
  1429.         WESetViewRect(&fr, macWE);
  1430.     }
  1431.  
  1432.     WEUpdate(updateRgn, macWE);
  1433.     // not necessary -- err = WESetInfo(wePort, &macPort, macWE);
  1434.     DisposeRgn(updateRgn);
  1435.  
  1436.     if (printing)
  1437.     {
  1438.         err = WESetInfo(wePort, (Ptr)&macPort, macWE);
  1439.         WEFeatureFlag(weFDrawOffscreen, oldOffscreen, macWE);
  1440.         WEFeatureFlag(weFOutlineHilite, oldOutline, macWE);
  1441.     }
  1442. }
  1443.  
  1444.  
  1445. /********************************************************\
  1446.  Activate - activate the pane
  1447. \********************************************************/
  1448.  
  1449. void CWASTEText::Activate()
  1450. {
  1451. #if WASTE_VERSION == 0x01000000
  1452.     TSMDocumentID aTSMDocument;
  1453. #endif
  1454.  
  1455.     if (curWASTEText==this) // already active
  1456.     {
  1457.         return;
  1458.     }
  1459.     
  1460.     CAbstractText::Activate();
  1461.     
  1462.     // deactivate old WASTEText
  1463.     if (curWASTEText!=NULL) curWASTEText->Deactivate();
  1464.     Prepare();
  1465.     CalcWERects();
  1466.     WEActivate(macWE);
  1467.     curWASTEText = this;
  1468.  
  1469. #if WASTE_VERSION == 0x01000000
  1470.     if (!editable)
  1471.     {
  1472.         // if not editable, deactivate TSM so inline input won't work
  1473.         // WASTE 1.1 adds a readonly flag so we don't have to do this
  1474.         if (gUsingTSM)
  1475.         {
  1476.             if (WEGetInfo(weTSMDocumentID, (Ptr)&aTSMDocument, macWE) == noErr)
  1477.             {
  1478.                 if (aTSMDocument != NULL)
  1479.                     DeactivateTSMDocument(aTSMDocument);
  1480.             }
  1481.         }
  1482.     }
  1483. #endif
  1484. }
  1485.  
  1486. /********************************************************\
  1487.  Deactivate - deactivate the pane
  1488. \********************************************************/
  1489.  
  1490. void CWASTEText::Deactivate()
  1491. {
  1492.     CAbstractText::Deactivate();
  1493.  
  1494.     Prepare();
  1495.     WEStopInlineSession(macWE);
  1496.     if (macWE)
  1497.     {
  1498.         CalcWERects();
  1499.         WEDeactivate(macWE);
  1500.     }
  1501.     curWASTEText = NULL;
  1502. }
  1503.  
  1504. /********************************************************\
  1505.  SetSelection - set what text is selected
  1506. \********************************************************/
  1507.  
  1508. void CWASTEText::SetSelection(long selStart, long selEnd, Boolean fRedraw)
  1509. {
  1510.     short wasActive, wasOutline;
  1511.     Boolean oldRedraw;
  1512.  
  1513.     Prepare();    
  1514.     if (!fRedraw)
  1515.     {
  1516.         oldRedraw = InhibitRedraw(true);
  1517.     }
  1518.     WESetSelection(selStart, selEnd, macWE);
  1519.     if (!fRedraw)
  1520.     {
  1521.         InhibitRedraw(oldRedraw);
  1522.     }
  1523. }
  1524.  
  1525. /********************************************************\
  1526.  Clear - clear the text
  1527.     Deactivates text before clearing to prevent
  1528.     highlighting from showing up
  1529. \********************************************************/
  1530.  
  1531. void CWASTEText::Clear(void)
  1532. {
  1533.     Boolean    saveAllocState;
  1534.     OSErr    err;
  1535. #if WASTE_VERSION >= 0x01100000
  1536.     Boolean wasReadOnly;
  1537. #endif
  1538.  
  1539.     Prepare();
  1540.     
  1541.     SetSelection(0, 0x7FFFFFFF, false);
  1542.     saveAllocState = SetAllocation(kAllocCanFail);
  1543. #if WASTE_VERSION >= 0x01100000
  1544.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  1545. #endif
  1546.     err = WEDelete(macWE);
  1547. #if WASTE_VERSION >= 0x01100000
  1548.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  1549. #endif
  1550.     SetAllocation(saveAllocState);
  1551.     
  1552.     AdjustBounds();
  1553.     ScrollToSelection();
  1554. //    itsSupervisor->Notify(NULL); // can't undo
  1555.     FailOSErr(err);
  1556.     
  1557.     Refresh();
  1558.  
  1559. }
  1560.  
  1561. /********************************************************\
  1562.  SetTextPtr - set the text to a block of memory
  1563. \********************************************************/
  1564.  
  1565. void CWASTEText::SetTextPtr(Ptr textPtr, long numChars)
  1566. {
  1567.     Boolean        saveAllocState;
  1568.     OSErr        err;
  1569. #if WASTE_VERSION >= 0x01100000
  1570.     Boolean        wasReadOnly;
  1571. #endif
  1572.  
  1573.     Prepare();
  1574.     if (!ReallyVisible())
  1575.         SetOrigin(-10000, -10000);
  1576.     
  1577.     SetSelection(0, 0x7FFFFFFF, false);
  1578. #if WASTE_VERSION >= 0x01100000
  1579.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  1580. #endif
  1581.     FailOSErr(WEDelete(macWE));
  1582.     CheckInsertion(numChars, 0, FALSE);
  1583.     saveAllocState = SetAllocation(kAllocCanFail);
  1584. #if WASTE_VERSION >= 0x01100000
  1585.     err = WEInsert(textPtr, numChars, NULL, NULL, macWE);
  1586.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  1587. #else
  1588.     err = WEInsert(textPtr, numChars, NULL, macWE);
  1589. #endif
  1590.     SetAllocation(saveAllocState);
  1591.  
  1592.     AdjustBounds();
  1593.     Refresh();
  1594.  
  1595. //    itsSupervisor->Notify(NULL); // can't undo
  1596.     
  1597.     FailOSErr(err);
  1598. }
  1599.  
  1600. /********************************************************\
  1601.  StopInlineSession - stop inline session, confirm text
  1602. \********************************************************/
  1603.  
  1604. void CWASTEText::StopInlineSession(void)
  1605. {
  1606.     WEStopInlineSession(macWE);
  1607. }
  1608.  
  1609. /********************************************************\
  1610.  SetOutlineHighliting - turns on or off outline
  1611.      highliting and returns old setting
  1612. \********************************************************/
  1613.  
  1614. Boolean CWASTEText::SetOutlineHighliting(Boolean hilite)
  1615. {
  1616.     Boolean oldValue;
  1617.     
  1618.     oldValue = (WEFeatureFlag(weFOutlineHilite, 
  1619.         hilite ? weBitSet : weBitClear, macWE) == weBitSet);
  1620.         
  1621.     return oldValue;
  1622. }
  1623.  
  1624. /********************************************************\
  1625.  GetTextHandle - get a handle to the text
  1626.      This is not a copy of the handle, but the real thing
  1627. \********************************************************/
  1628.  
  1629. Handle CWASTEText::GetTextHandle()
  1630. {
  1631.     return( (Handle) WEGetText(macWE));
  1632. }
  1633.  
  1634. /********************************************************\
  1635.  CopyTextRange - return a handle to a copy of the
  1636.      indicated range of text
  1637. \********************************************************/
  1638.  
  1639. Handle CWASTEText::CopyTextRange(long start, long end)
  1640. {
  1641.     Handle    h;
  1642.     long    len;
  1643.     
  1644. #if (TCL_VERSION) >= 0x02000000
  1645.     end = TCLMin(end, WEGetTextLength(macWE));
  1646.     len = TCLMax(end - start, 0);
  1647. #else
  1648.     end = Min(end, WEGetTextLength(macWE));
  1649.     len = Max(end - start, 0);
  1650. #endif
  1651.     h = NewHandleCanFail(len);
  1652.     FailNIL(h);
  1653.     if (len > 0)
  1654.         BlockMoveData( (char*)*(WEGetText(macWE)) + start, *h, len);
  1655.     
  1656.     return h;
  1657. }
  1658.  
  1659. /********************************************************\
  1660.  CopyRangeWithStyle - return a handle to the text and
  1661.      styles in a range.  Handles must be previously
  1662.      created with NewHandle();
  1663. \********************************************************/
  1664.  
  1665. void CWASTEText::CopyRangeWithStyle(long start, long end, Handle hText,
  1666.     StScrpHandle hStyles)
  1667. {
  1668.     Boolean        saveAllocState;
  1669.     OSErr        err;
  1670.     
  1671.     saveAllocState = SetAllocation(kAllocCanFail);
  1672. #if WASTE_VERSION >= 0x01100000
  1673.     err = WECopyRange(start, end, hText, hStyles, NULL, macWE);
  1674. #else
  1675.     err = WECopyRange(start, end, hText, hStyles, macWE);
  1676. #endif
  1677.     SetAllocation(saveAllocState);
  1678.     FailOSErr(err);
  1679. }
  1680.  
  1681. #if WASTE_VERSION >= 0x01100000
  1682. /********************************************************\
  1683.  CopyRangeWithStyleSoup - return a handle to the text and
  1684.      styles and soup in a range.  Handles must be previously
  1685.      created with NewHandle();
  1686. \********************************************************/
  1687.  
  1688. void CWASTEText::CopyRangeWithStyleSoup(long start, long end, Handle hText,
  1689.     StScrpHandle hStyles, WESoupHandle hSoup)
  1690. {
  1691.     Boolean        saveAllocState;
  1692.     OSErr        err;
  1693.     
  1694.     saveAllocState = SetAllocation(kAllocCanFail);
  1695.     err = WECopyRange(start, end, hText, hStyles, hSoup, macWE);
  1696.     SetAllocation(saveAllocState);
  1697.     FailOSErr(err);
  1698. }
  1699. #endif
  1700.  
  1701. /********************************************************\
  1702.  InsertTextPtr - insert a block of text
  1703. \********************************************************/
  1704.  
  1705. void CWASTEText::InsertTextPtr(Ptr text, long length, Boolean fRedraw)
  1706. {
  1707.     Boolean        saveAllocState;
  1708.     OSErr        err;
  1709.     Boolean        wasReadOnly;
  1710.     Boolean        oldRedraw;
  1711.  
  1712.     Prepare();
  1713.     if (!ReallyVisible())
  1714.         SetOrigin(-10000, -10000);
  1715.  
  1716.     CheckInsertion(length, 0, TRUE);
  1717.     saveAllocState = SetAllocation(kAllocCanFail);
  1718.  
  1719.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  1720.  
  1721. #if WASTE_VERSION >= 0x01100000
  1722.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  1723.  
  1724.     err = WEInsert(text, length, NULL, NULL, macWE);
  1725.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  1726. #else
  1727.     err = WEInsert(text, length, NULL, macWE);
  1728. #endif
  1729.     SetAllocation(saveAllocState);
  1730.  
  1731.     AdjustBounds();
  1732.  
  1733. //    itsSupervisor->Notify(NULL); // can't undo
  1734.  
  1735.     if (!fRedraw) InhibitRedraw(oldRedraw);
  1736.  
  1737.     FailOSErr(err);
  1738. }
  1739.  
  1740. /********************************************************\
  1741.  InsertWithStyle -- insert text along with style
  1742. \********************************************************/
  1743.  
  1744. void CWASTEText::InsertWithStyle(Ptr text, long length, StScrpHandle hStyles,
  1745.         Boolean fRedraw)
  1746. {
  1747.     Boolean        saveAllocState;
  1748.     OSErr        err;
  1749.     Boolean        oldRedraw;
  1750. #if WASTE_VERSION >= 0x01100000
  1751.     Boolean        wasReadOnly;
  1752. #else
  1753.     long        i, numStyles;
  1754.     StScrpPtr    styles;
  1755. #endif
  1756.  
  1757.     Prepare();
  1758.     if (!ReallyVisible())
  1759.         SetOrigin(-10000, -10000);
  1760.     CheckInsertion(length, hStyles ? GetHandleSize((Handle) hStyles) : 0, TRUE);
  1761.  
  1762.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  1763.  
  1764. #if WASTE_VERSION == 0x01000000
  1765.     //    Fix style entries which have a font size of 0
  1766.     // newer versions of WASTE do this for us
  1767.     if (hStyles)
  1768.     {
  1769.         styles = *hStyles;
  1770.         
  1771.         numStyles = styles->scrpNStyles;
  1772.         for (i = 0; i < numStyles; i++)
  1773.             if (styles->scrpStyleTab[i].scrpSize == 0)
  1774.                 styles->scrpStyleTab[i].scrpSize = 12;
  1775.     }
  1776. #endif
  1777.  
  1778.     saveAllocState = SetAllocation(kAllocCanFail);
  1779. #if WASTE_VERSION >= 0x01100000
  1780.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  1781.     err = WEInsert(text, length, hStyles, NULL, macWE);
  1782.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  1783. #else
  1784.     err = WEInsert(text, length, hStyles, macWE);
  1785. #endif
  1786.     SetAllocation(saveAllocState);
  1787.  
  1788.     AdjustBounds();
  1789. //    itsSupervisor->Notify(NULL); // can't undo
  1790.  
  1791.     if (!fRedraw) InhibitRedraw(oldRedraw);
  1792.  
  1793.     FailOSErr(err);
  1794. }
  1795.  
  1796. #if WASTE_VERSION >= 0x01100000
  1797. /********************************************************\
  1798.  InsertWithStyleSoup -- insert text along with style
  1799.     and soup
  1800. \********************************************************/
  1801.  
  1802. void CWASTEText::InsertWithStyleSoup(Ptr text, long length, StScrpHandle hStyles,
  1803.         WESoupHandle hSoup, Boolean fRedraw)
  1804. {
  1805.     Boolean        saveAllocState;
  1806.     OSErr        err;
  1807.     Boolean        wasReadOnly;
  1808.     Boolean        oldRedraw;
  1809.  
  1810.     Prepare();
  1811.     if (!ReallyVisible())
  1812.         SetOrigin(-10000, -10000);
  1813.     CheckInsertion(length, hStyles ? GetHandleSize((Handle) hStyles) : 0, TRUE);
  1814.  
  1815.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  1816.  
  1817.     saveAllocState = SetAllocation(kAllocCanFail);
  1818.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  1819.     err = WEInsert(text, length, hStyles, hSoup, macWE);
  1820.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  1821.     SetAllocation(saveAllocState);
  1822.  
  1823.     AdjustBounds();
  1824.  
  1825. //    itsSupervisor->Notify(NULL); // can't undo
  1826.  
  1827.     if (!fRedraw) InhibitRedraw(oldRedraw);
  1828.  
  1829.     FailOSErr(err);
  1830. }
  1831. #endif
  1832.  
  1833.  
  1834. /********************************************************\
  1835.  TypeChar - type a character
  1836. \********************************************************/
  1837.  
  1838. void CWASTEText::TypeChar(char theChar, short theModifers)
  1839. {
  1840.     Boolean        saveAllocState;
  1841.  
  1842.     Prepare();
  1843.  
  1844.     CheckInsertion(1, 0, TRUE);
  1845.     saveAllocState = SetAllocation(kAllocCanFail);
  1846.  
  1847.     WEKey(theChar, theModifers, macWE);
  1848.     SetAllocation(saveAllocState);
  1849.  
  1850.     AdjustBounds();
  1851.     ScrollToSelection();
  1852. }
  1853.  
  1854. /********************************************************\
  1855.  CalcWERects - Sets the DestRect and ViewRect fields
  1856.      used by WASTE
  1857. \********************************************************/
  1858.  
  1859. void CWASTEText::CalcWERects()
  1860. {
  1861.     LongRect    fr, dr;
  1862.     Rect        r;
  1863.  
  1864.     // Prepare the destination and view rectangles
  1865.  
  1866.     WEGetDestRect(&dr, macWE);
  1867.     dr.top = 0;
  1868.     dr.bottom = GetHeight(0, MAXLONG);
  1869.     OffsetLongRect(&dr, -(dr.left + frame.left), -(dr.top + frame.top));
  1870.     FrameToQDR(&frame, &r);
  1871.     OffsetLongRect(&dr, r.left, r.top);
  1872.     dr.right = (lineWidth > 0) ? dr.left + lineWidth : frame.right;
  1873. //    dr.top += textMargin;  // removed in WASTE TCL 2.0
  1874. //    dr.bottom += textMargin; // removed in WASTE TCL 2.0
  1875.     dr.left += textMargin;
  1876.     dr.right -= textMargin;
  1877.     WESetDestRect(&dr, macWE);
  1878.  
  1879.     GetAperture(&fr);
  1880.     FrameToQDR(&fr, &r);
  1881.     QDToLongRect(&r, &fr);
  1882.     WESetViewRect(&fr, macWE);
  1883. }
  1884.  
  1885. /********************************************************\
  1886.  ResizeFrame - resize the frame when the size of the
  1887.      pane changes
  1888. \********************************************************/
  1889.  
  1890. void CWASTEText::ResizeFrame(Rect *delta)
  1891. {
  1892.     Boolean    saveAllocState;
  1893.     OSErr        err;
  1894.  
  1895.     CAbstractText::ResizeFrame(delta);
  1896.  
  1897.     CalcWERects();    
  1898.  
  1899.     if (lineWidth < 0 && (delta->left !=0 || delta->right != 0))
  1900.     {
  1901.         saveAllocState = SetAllocation(kAllocCanFail);
  1902.         err = WECalText(macWE);
  1903.         SetAllocation(saveAllocState);
  1904.         CalcWERects();    
  1905.     }
  1906.  
  1907.     AdjustBounds();
  1908. }
  1909.  
  1910. /********************************************************\
  1911.  AdjustBounds - change the size of the CWASTEText to
  1912.      match that in the WASTE record
  1913. \********************************************************/
  1914.  
  1915. void CWASTEText::AdjustBounds()
  1916. {
  1917.     LongRect    oldBounds;
  1918.     long          newHeight;
  1919.     long        hFix = 0, vFix = 0;
  1920.  
  1921.     oldBounds = bounds;
  1922.     newHeight = GetHeight(0, MAXLONG); // changed from MAXINT WASTE TCL 2.0
  1923.     
  1924.     bounds.left = bounds.top = 0;
  1925.     bounds.bottom = newHeight;
  1926.  
  1927.     if (lineWidth > 0) 
  1928.     {
  1929.         bounds.right = lineWidth;
  1930.     }
  1931.     else
  1932.     {
  1933.         bounds.right = frame.right - frame.left;
  1934.     }
  1935.         
  1936.     bounds.right = (bounds.right - 1) / hScale + 1;
  1937.  
  1938.     if (itsScrollPane != NULL)
  1939.     {
  1940.         itsScrollPane->AdjustScrollMax();
  1941.         itsScrollPane->Calibrate();
  1942.     }
  1943. }
  1944.  
  1945. /********************************************************\
  1946.  FindLine - return the line on which the character
  1947.      at charPos is on.
  1948. \********************************************************/
  1949.  
  1950. long CWASTEText::FindLine(long charPos)
  1951. {
  1952.     long    lineNo;
  1953.     
  1954. #if WASTE_VERSION >= 0x01100000
  1955.     lineNo = WEOffsetToLine(charPos, macWE);
  1956. #else
  1957.     lineNo = _WEOffsetToLine(charPos, macWE);
  1958. #endif
  1959.     if (charPos == WEGetTextLength(macWE) && 
  1960.         ((char*)(*GetTextHandle()))[GetLength()-1] == 13)
  1961.         lineNo++;
  1962.  
  1963.     return (lineNo);
  1964.     
  1965. }
  1966.  
  1967. /********************************************************\
  1968.  GetLength - return the length of the text
  1969. \********************************************************/
  1970.  
  1971. long CWASTEText::GetLength()
  1972. {
  1973.     return WEGetTextLength(macWE);
  1974. }
  1975.  
  1976. /********************************************************\
  1977.  SetFontNumber - set the font of the selection
  1978. \********************************************************/
  1979.  
  1980. void CWASTEText::SetFontNumber(short aFontNumber)
  1981. {
  1982.     TextStyle    style;
  1983.     
  1984.     style.tsFont = aFontNumber;
  1985.     SetStyle( doFont, &style, TRUE);
  1986. //    itsSupervisor->Notify(NULL); // can't undo
  1987.  
  1988. }
  1989.  
  1990. /********************************************************\
  1991.  SetFontNumberAll - set the font of all of the text
  1992. \********************************************************/
  1993.  
  1994. void CWASTEText::SetFontNumberAll(short aFontNumber)
  1995. {
  1996.     TempSelectAll();
  1997.     SetFontNumber(aFontNumber);
  1998.     RestoreSelection();
  1999. //    itsSupervisor->Notify(NULL); // can't undo
  2000. }
  2001.  
  2002. /********************************************************\
  2003.  SetFontNameAll - set the font of the selection
  2004. \********************************************************/
  2005.  
  2006. void CWASTEText::SetFontNameAll(Str255 aFontName)
  2007. {
  2008.     TempSelectAll();
  2009.     SetFontName(aFontName);
  2010.     RestoreSelection();
  2011. //    itsSupervisor->Notify(NULL); // can't undo
  2012. }
  2013.  
  2014. /********************************************************\
  2015.  SetFontStyle - set the font style of the selection
  2016. \********************************************************/
  2017.  
  2018. void CWASTEText::SetFontStyle(short aStyle)
  2019. {
  2020.     TextStyle    style;
  2021.     short        mode = doFace;
  2022.     
  2023.     style.tsFace = aStyle;
  2024.     if (aStyle != NOTHING)
  2025.         mode += doToggle;
  2026.     SetStyle( mode, &style, TRUE);
  2027. //    itsSupervisor->Notify(NULL); // can't undo
  2028. }
  2029.  
  2030. /********************************************************\
  2031.  SetFontStyleAll - set the font style of all of the text
  2032. \********************************************************/
  2033.  
  2034. void CWASTEText::SetFontStyleAll(short aStyle)
  2035. {
  2036.     TempSelectAll();
  2037.     SetFontStyle(aStyle);
  2038.     RestoreSelection();
  2039. //    itsSupervisor->Notify(NULL); // can't undo
  2040. }
  2041.  
  2042. /********************************************************\
  2043.  SetFontSize - set the font size of the selection
  2044. \********************************************************/
  2045.  
  2046. void CWASTEText::SetFontSize(short aSize)
  2047. {
  2048.     TextStyle    style;
  2049.     
  2050.     style.tsSize = aSize;
  2051.     SetStyle( doSize, &style, TRUE);
  2052. //    itsSupervisor->Notify(NULL); // can't undo
  2053. }
  2054.  
  2055. /********************************************************\
  2056.  SetFontSizeAll - set the font size of all of the text
  2057. \********************************************************/
  2058.  
  2059. void CWASTEText::SetFontSizeAll(short aSize)
  2060. {
  2061.     TempSelectAll();
  2062.     SetFontSize(aSize);
  2063.     RestoreSelection();
  2064. //    itsSupervisor->Notify(NULL); // can't undo
  2065. }
  2066.  
  2067. /********************************************************\
  2068.  SetFontColor - set the color of the selection
  2069. \********************************************************/
  2070.  
  2071. void CWASTEText::SetFontColor(RGBColor *aFontColor)
  2072. {
  2073.     TextStyle    style;
  2074.     
  2075.     style.tsColor = (*aFontColor);
  2076.     SetStyle(doColor, &style, TRUE);
  2077. //    itsSupervisor->Notify(NULL); // can't undo
  2078.  
  2079. }
  2080.  
  2081. /********************************************************\
  2082.  SetFontColorAll - set the font of all of the text
  2083. \********************************************************/
  2084.  
  2085. void CWASTEText::SetFontColorAll(RGBColor *aFontColor)
  2086. {
  2087.     TempSelectAll();
  2088.     SetFontColor(aFontColor);
  2089.     RestoreSelection();
  2090. //    itsSupervisor->Notify(NULL); // can't undo
  2091. }
  2092.  
  2093. /********************************************************\
  2094.  SetTextMode - currently not implemented
  2095. \********************************************************/
  2096.  
  2097. void CWASTEText::SetTextMode(short aMode)
  2098. {
  2099.     return;
  2100. }
  2101.  
  2102. /********************************************************\
  2103.  SetAlignment - set the alignment
  2104. \********************************************************/
  2105.  
  2106. void CWASTEText::SetAlignment(short anAlignment)
  2107. {
  2108.     WESetAlignment(anAlignment, macWE);
  2109.     
  2110.     Refresh();
  2111. }
  2112.  
  2113. /********************************************************\
  2114.  SetAlignCmd - set the alignment
  2115. \********************************************************/
  2116.  
  2117. void CWASTEText::SetAlignCmd(long anAlignCmd)
  2118. {
  2119.     short teAlign;
  2120.     
  2121.     alignCmd = anAlignCmd;
  2122.     switch( alignCmd)
  2123.     {
  2124.         case cmdAlignLeft:
  2125.             teAlign = weFlushLeft;
  2126.             break;
  2127.         case cmdAlignCenter:
  2128.             teAlign = weCenter;
  2129.             break;
  2130.         case cmdAlignRight:
  2131.             teAlign = weFlushRight;
  2132.             break;
  2133.         case cmdJustify:        //mf
  2134.             teAlign = weJustify;
  2135.             break;
  2136.         default:
  2137.             teAlign = weFlushDefault;
  2138.     }
  2139.     SetAlignment(teAlign);
  2140. }
  2141.  
  2142. /********************************************************\
  2143.  SetSpacingCmd - not really supported
  2144. \********************************************************/
  2145.  
  2146. void CWASTEText::SetSpacingCmd(long aSpacingCmd)
  2147. {
  2148.     spacingCmd = cmdSingleSpace;
  2149.     
  2150.     // only single-spaced text is supported.
  2151.     
  2152.     SetWholeLines(wholeLines);
  2153.      CalcAperture();
  2154.     AdjustBounds();
  2155.  
  2156. }
  2157.  
  2158. /********************************************************\
  2159.  SetTheStyleScrap - set the style of a given range
  2160.      caller disposes handle
  2161. \********************************************************/
  2162.  
  2163. void CWASTEText::SetTheStyleScrap(long rangeStart, long rangeEnd,
  2164.             StScrpHandle styleScrap, Boolean fRedraw)
  2165. {
  2166.     Boolean        saveAllocState;
  2167.     OSErr        err;
  2168.     long        selStart, selEnd;
  2169.     Boolean        oldRedraw;
  2170.     
  2171.     Prepare();
  2172.  
  2173.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  2174.  
  2175.     if (!ReallyVisible())
  2176.         SetOrigin(-10000, -10000);
  2177.     saveAllocState = SetAllocation(kAllocCanFail);
  2178.     WEGetSelection(&selStart, &selEnd, macWE);
  2179.     SetSelection(rangeStart, rangeEnd, FALSE);
  2180.     err = WEUseStyleScrap(styleScrap, macWE);
  2181.     if (err == noErr)
  2182.     {
  2183.         SetSelection(selStart, selEnd, false);
  2184.         err = WECalText( macWE);
  2185.     }
  2186.  
  2187.     SetAllocation(saveAllocState);
  2188.     AdjustBounds();
  2189. //    itsSupervisor->Notify(NULL); // can't undo
  2190.  
  2191.     if (!fRedraw) InhibitRedraw(oldRedraw);
  2192.  
  2193.     FailOSErr(err);
  2194. }
  2195.  
  2196. /********************************************************\
  2197.  SetStyle - set the style of the current selection
  2198. \********************************************************/
  2199.  
  2200. void CWASTEText::SetStyle(short mode, TextStyle *newStyle, Boolean fRedraw)
  2201. {
  2202.     Boolean        saveAllocState;
  2203.     OSErr        err;
  2204. #if WASTE_VERSION >= 0x01100000
  2205.     Boolean        wasReadOnly;
  2206. #endif
  2207.     Boolean        oldRedraw;
  2208.  
  2209.     Prepare();
  2210.  
  2211.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  2212.  
  2213.     if (!ReallyVisible())
  2214.         SetOrigin(-10000, -10000);
  2215.     saveAllocState = SetAllocation(kAllocCanFail);
  2216. #if WASTE_VERSION >= 0x01100000
  2217.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  2218. #endif
  2219.     err = WESetStyle( mode, newStyle, macWE);
  2220. #if WASTE_VERSION >= 0x01100000
  2221.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  2222. #endif
  2223.     SetAllocation(saveAllocState);
  2224.  
  2225.     if (err == noErr)
  2226.     {
  2227.         SetSpacingCmd(spacingCmd);
  2228.         SetWholeLines(wholeLines);
  2229.     }
  2230.     
  2231.     AdjustBounds();
  2232.  
  2233. //    itsSupervisor->Notify(NULL); // can't undo
  2234.  
  2235.     if (!fRedraw) InhibitRedraw(oldRedraw);
  2236.  
  2237.     FailOSErr(err);
  2238. }
  2239.  
  2240. /********************************************************\
  2241.  GetHeight - get the height of the indicated lines
  2242. \********************************************************/
  2243.  
  2244. long CWASTEText::GetHeight(long startLine, long endLine)
  2245. {
  2246.     long height;
  2247.     long nLines;
  2248.     
  2249.     nLines = GetNumLines();
  2250.     height = WEGetHeight( startLine - 1, endLine, macWE);
  2251.     if (endLine >= nLines && ((char*)(*GetTextHandle()))[GetLength()-1] == 13)
  2252.         height += WEGetHeight(nLines - 2, nLines - 1, macWE);
  2253.  
  2254.     return height;
  2255. }
  2256.  
  2257. /********************************************************\
  2258.  GetCharOffset - return offset of character at point in
  2259.      frame coords
  2260. \********************************************************/
  2261.  
  2262. long CWASTEText::GetCharOffset(LongPt *aPt)
  2263. {
  2264.     Point    qdPt;
  2265.     LongPt lPt;
  2266.     char edge;
  2267.     
  2268.     Prepare();
  2269.     FrameToQD( aPt, &qdPt);
  2270.     lPt.v = qdPt.v;
  2271.     lPt.h = qdPt.h;
  2272.     
  2273.     return WEGetOffset( &lPt, &edge, macWE);
  2274.     
  2275. }
  2276.  
  2277. /********************************************************\
  2278.  GetCharPoint - return the position of the character in
  2279.      Frame coordinates
  2280. \********************************************************/
  2281.  
  2282. void CWASTEText::GetCharPoint( long offset, LongPt *aPt)
  2283. {
  2284.     Point    qdPt;
  2285.     LongPt lPt;
  2286.     short lineHeight;
  2287.     
  2288. #if (TCL_VERSION) >= 0x02000000
  2289.     TCL_ASSERT( offset <= MAXLONG);
  2290. #else
  2291.     ASSERT( offset <= MAXLONG);
  2292. #endif
  2293.     
  2294.     Prepare();
  2295.     WEGetPoint(offset, &lPt, &lineHeight, macWE);
  2296.     qdPt.h = lPt.h;
  2297.     qdPt.v = lPt.v;
  2298.     QDToFrame( qdPt, aPt);
  2299. }
  2300.  
  2301. /********************************************************\
  2302.  GetTextStyle - return style of selection
  2303. \********************************************************/
  2304.  
  2305. void CWASTEText::GetTextStyle(short *whichAttributes, TextStyle *aStyle)
  2306. {
  2307. #if WASTE_VERSION >= 0x01204004
  2308.     WEContinuousStyle((unsigned short *)whichAttributes, aStyle, macWE);
  2309. #else
  2310.     WEContinuousStyle(whichAttributes, aStyle, macWE);
  2311. #endif
  2312.  
  2313. }
  2314.  
  2315. /********************************************************\
  2316.  GetTextStyles -- return a style scrap for all of the
  2317.      text.
  2318. \********************************************************/
  2319.  
  2320. StScrpHandle CWASTEText::GetTextStyles(void)
  2321. {
  2322.     OSErr            err;
  2323.     StScrpHandle    styles;
  2324.     Boolean            saveAllocState;
  2325.     
  2326.     styles = (StScrpHandle) NewHandleCanFail(0);
  2327.     saveAllocState = SetAllocation(kAllocCanFail);
  2328. #if WASTE_VERSION >= 0x01100000
  2329.     err = WECopyRange(0, WEGetTextLength(macWE), NULL, styles, NULL, macWE);
  2330. #else
  2331.     err = WECopyRange(0, WEGetTextLength(macWE), NULL, styles, macWE);
  2332. #endif
  2333.     SetAllocation(saveAllocState);
  2334.     if (err != noErr)
  2335.     {
  2336.         DisposeHandle((Handle) styles);
  2337.         FailOSErr(err);
  2338.     }
  2339.  
  2340.     return (styles);
  2341. }
  2342.  
  2343. /********************************************************\
  2344.  GetCharStyle - return style of one character
  2345. \********************************************************/
  2346.  
  2347. void CWASTEText::GetCharStyle(long charOffset, TextStyle *theStyle)
  2348. {
  2349.     WERunInfo runInfo;
  2350.  
  2351.     WEGetRunInfo(charOffset, &runInfo, macWE);
  2352.     *theStyle = runInfo.runStyle;
  2353. }
  2354.  
  2355. /********************************************************\
  2356. GetRunInfo - get run info in a WERunInfo structure
  2357. \********************************************************/
  2358.  
  2359. void CWASTEText::GetRunInfo(long offset, WERunInfo *runInfo)
  2360. {
  2361.     WEGetRunInfo(offset, runInfo, macWE);
  2362. }
  2363.  
  2364. /********************************************************\
  2365. GetChar -- return the character at an offset, handling
  2366.     2 byte characters correctly
  2367. \********************************************************/
  2368.  
  2369. short CWASTEText::GetChar(long offset)
  2370. {
  2371.     return WEGetChar(offset, macWE);
  2372. }
  2373.  
  2374. /********************************************************\
  2375.  GetSpacingCmd - not really supported
  2376. \********************************************************/
  2377.  
  2378. long CWASTEText::GetSpacingCmd(void)
  2379. {
  2380.     return spacingCmd;
  2381. }
  2382.  
  2383. /********************************************************\
  2384.  GetAlignCmd - not really supported
  2385. \********************************************************/
  2386.  
  2387. long CWASTEText::GetAlignCmd(void)
  2388. {
  2389.     return alignCmd;
  2390. }
  2391.  
  2392. /********************************************************\
  2393.  GetTheStyleScrap -- get a scrap handle of the styles
  2394.      of the selection
  2395. \********************************************************/
  2396.  
  2397. StScrpHandle CWASTEText::GetTheStyleScrap(void)
  2398. {
  2399.     Boolean        saveAllocState;
  2400.     OSErr        err;
  2401.     long        selStart, selEnd;
  2402.     StScrpHandle h;
  2403.  
  2404.     GetSelection(&selStart, &selEnd);
  2405.  
  2406.     h=(StScrpHandle)NewHandleCanFail(1);
  2407.     FailNIL(h);
  2408.     saveAllocState = SetAllocation(kAllocCanFail);
  2409. #if WASTE_VERSION >= 0x01100000
  2410.     err = WECopyRange(selStart, selEnd, (Handle)NULL, h, NULL, macWE);
  2411. #else
  2412.     err = WECopyRange(selStart, selEnd, (Handle)NULL, h, macWE);
  2413. #endif
  2414.     SetAllocation(saveAllocState);
  2415.     FailOSErr(err);
  2416.     
  2417.     return h;
  2418. }
  2419.  
  2420. #if WASTE_VERSION >= 0x01100000
  2421. /********************************************************\
  2422.  GetTheSoup - return the soup of the selection
  2423. \********************************************************/
  2424.  
  2425. WESoupHandle CWASTEText::GetTheSoup(void)
  2426. {
  2427.     Boolean        saveAllocState;
  2428.     OSErr        err;
  2429.     long        selStart, selEnd;
  2430.     WESoupHandle h;
  2431.  
  2432.     GetSelection(&selStart, &selEnd);
  2433.  
  2434.     h=(WESoupHandle)NewHandleCanFail(1);
  2435.     FailNIL(h);
  2436.     saveAllocState = SetAllocation(kAllocCanFail);
  2437.     err = WECopyRange(selStart, selEnd, (Handle)NULL, NULL, h, macWE);
  2438.     SetAllocation(saveAllocState);
  2439.     FailOSErr(err);
  2440.     
  2441.     return h;
  2442. }
  2443. #endif
  2444.  
  2445. /********************************************************\
  2446.  GetNumLines - return the number of lines
  2447. \********************************************************/
  2448.  
  2449. long CWASTEText::GetNumLines(void)
  2450. {
  2451.     long nLines = WECountLines(macWE);
  2452.  
  2453.     if (!GetLength()) return 0;
  2454.     // add 1 if last character is a newline
  2455.     if (((char*)(*GetTextHandle()))[GetLength()-1] == 13)
  2456.         nLines++;
  2457.     return nLines;
  2458. }
  2459.  
  2460. /********************************************************\
  2461.  GetSelection - get the position of the start and end
  2462.      of the selection
  2463. \********************************************************/
  2464.  
  2465. void CWASTEText::GetSelection(long *selStart, long *selEnd)
  2466. {
  2467.     WEGetSelection(selStart, selEnd, macWE);
  2468. }
  2469.  
  2470. /********************************************************\
  2471.  HideSelection - not implemented
  2472. \********************************************************/
  2473.  
  2474. void CWASTEText::HideSelection(Boolean hide, Boolean redraw)
  2475. {
  2476.     return;
  2477. }
  2478.  
  2479. /********************************************************\
  2480.  GetSteps - get the size of the scrolling steps
  2481.      Step sizes hard coded in
  2482. \********************************************************/
  2483.  
  2484. void CWASTEText::GetSteps(short *hStep, short *vStep)
  2485. {
  2486.     long        nLines,
  2487.                 height;
  2488.  
  2489.     nLines = GetNumLines();
  2490.     height = GetHeight(0, MAXLONG); // changed from MAXINT in WASTETCL 2.0
  2491.     *hStep = 20;
  2492.     if (nLines)
  2493. #if (TCL_VERSION) >= 0x02000000
  2494.         *vStep = TCLMin(height / nLines, 30);
  2495. #else
  2496.         *vStep = Min(height / nLines, 30);
  2497. #endif
  2498.     else
  2499.         *vStep = height;
  2500. }
  2501.  
  2502. /********************************************************\
  2503.  AboutToPrint -- called right before printing
  2504. \********************************************************/
  2505.  
  2506. void CWASTEText::AboutToPrint(short *firstPage, short *lastPage)
  2507. {
  2508.     if (active)
  2509.     {
  2510.         Prepare();
  2511.         HidePen();
  2512.         WEDeactivate(macWE);
  2513.         ShowPen();
  2514.     }
  2515.  
  2516.     CAbstractText::AboutToPrint(firstPage, lastPage);
  2517. }
  2518.  
  2519.  
  2520. /********************************************************\
  2521.  Paginate -- figure out the number of pages
  2522. \********************************************************/
  2523. /*
  2524. void CWASTEText::Paginate(CPrinter *aPrinter, short pageWidth, short pageHeight)
  2525. {
  2526.     Boolean        saveAllocState;
  2527.     OSErr        err;
  2528.     LongRect    dr;
  2529.  
  2530.     WEGetDestRect(&dr, macWE);
  2531.     dr.right = dr.left + pageWidth;
  2532.     WESetDestRect(&dr, macWE);
  2533.     saveAllocState = SetAllocation(kAllocCanFail);
  2534.     err = WECalText(macWE);
  2535.     SetAllocation(saveAllocState);
  2536.     FailOSErr(err);
  2537.     printPageWidth = pageWidth;
  2538.     
  2539.     CAbstractText::Paginate(aPrinter, pageWidth, pageHeight);
  2540. }
  2541. */
  2542.  
  2543. /******************************************************************************
  2544.  
  2545.  Paginate {OVERRIDE}
  2546.  
  2547.  Override to fix pagination with mixed line heights.  Based on algorithm in
  2548. CAbstractText.
  2549.  
  2550. Thanks to Brian Matheny & Mark Alldritt
  2551.  
  2552. ******************************************************************************/
  2553.  
  2554. void CWASTEText::Paginate(CPrinter *aPrinter, short pageWidth, short pageHeight)
  2555. {
  2556.     short lineHeight, stripNum = 0;
  2557.     long currLine, numLines = GetNumLines(), pagePix = 0, printPix;
  2558.     Boolean    saveAllocState;
  2559.     OSErr        err;
  2560.     LongRect    dr;
  2561.  
  2562.     WEGetDestRect(&dr, macWE);
  2563.     dr.right = dr.left + pageWidth;
  2564.     WESetDestRect(&dr, macWE);
  2565.     saveAllocState = SetAllocation(kAllocCanFail);
  2566.     err = WECalText(macWE);
  2567.     SetAllocation(saveAllocState);
  2568.     FailOSErr(err);
  2569.     printPageWidth = pageWidth;
  2570.     
  2571.     if (fixedLineHeights)
  2572.     {
  2573.         inherited::Paginate(aPrinter, pageWidth, pageHeight);
  2574.     }
  2575.     else
  2576.     {
  2577.         aPrinter->ResetPagination();
  2578.         aPrinter->SetHorizPageBreak(1, pageWidth);
  2579.         printPix = 0;
  2580.     
  2581.         for (currLine = 1; currLine <= numLines; currLine++)
  2582.         {
  2583.             lineHeight = Get1Height(currLine);
  2584.             printPix += lineHeight;
  2585.             pagePix += lineHeight;
  2586.             if (pagePix > pageHeight)
  2587.             {
  2588.                 aPrinter->SetVertPageBreak(++stripNum, printPix - lineHeight);
  2589.                    pagePix = lineHeight;
  2590.             }
  2591.         }
  2592.         if (pagePix)
  2593.             aPrinter->SetVertPageBreak(++stripNum, printPix);
  2594.     }
  2595. }
  2596.  
  2597. /********************************************************\
  2598.  DonePrinting - called when printing is finished
  2599. \********************************************************/
  2600.  
  2601. void CWASTEText::DonePrinting()
  2602. {
  2603.     Boolean        saveAllocState;
  2604.     OSErr        err;
  2605.  
  2606.     CAbstractText::DonePrinting();
  2607.  
  2608.     if (active)
  2609.     {
  2610.         Prepare();
  2611.         HidePen();
  2612.         WEActivate(macWE);
  2613.         ShowPen();
  2614.     }
  2615.  
  2616.     CalcWERects();
  2617.     if (lineWidth < 0)
  2618.     {
  2619.         saveAllocState = SetAllocation(kAllocCanFail);
  2620.         err = WECalText( macWE);
  2621.         SetAllocation(saveAllocState);
  2622.     }
  2623. }
  2624.  
  2625. /********************************************************\
  2626.  Dawdle - do idle stuff
  2627. \********************************************************/
  2628.  
  2629. void CWASTEText::Dawdle(long *maxSleep)
  2630. {
  2631.     if (visible)
  2632.     {
  2633.         Prepare();
  2634.         WEIdle(NULL, macWE);
  2635.         *maxSleep = GetCaretTime();
  2636.     }
  2637. }
  2638.  
  2639. #if (TCL_VERSION) >= 0x02000000
  2640.  
  2641. #if VA_COMPATIBLE_IO
  2642. /********************************************************\
  2643.  GetFrom -- VA/CEditText compatible version 
  2644.     Code by Michael Grinner
  2645.     Note: Style and soup not saved
  2646. \********************************************************/
  2647.  
  2648. void CWASTEText::GetFrom(CStream& stream)
  2649. {
  2650. #ifdef TCL_OBJECT_IO
  2651.     Handle        volatile h = NULL;        // Text if len > 255
  2652.     Str255        text;                    // Text if len < 256
  2653.     short        txFont, txFace, txMode, txSize, textLength;
  2654.     short        reserved;
  2655.     GrafPtr        port;
  2656.  
  2657.     stream >> spacingCmd >> alignCmd >> reserved;
  2658.     stream >> txFace >> txMode >> txSize >> textLength;
  2659.  
  2660.     stream.GetStr255(text);            // Get font id
  2661.     GetFNum (text, &txFont);
  2662.  
  2663.  
  2664. // Go out of our way to avoid
  2665. //   creating a useless handle,
  2666. //   since most strings are small
  2667. //   and MM is *slow*.
  2668.  
  2669.     try_
  2670.     {
  2671.         if (textLength < 256)
  2672.         {
  2673.             stream.Get(&text[1], textLength);
  2674.             text[0] = textLength;
  2675.         }
  2676.         else
  2677.         {
  2678.             h = NewHandleCanFail(textLength);
  2679.             FailNIL(h);
  2680.             HLock(h);
  2681.             stream.Get(*h, textLength);
  2682.             HUnlock(h);
  2683.         }
  2684.  
  2685.         CAbstractText::GetFrom(stream); // Let base class restore and in it
  2686.  
  2687.         GetPort(&port);
  2688.         SetPort(macPort);
  2689.         TextFont(txFont);
  2690.         TextFace(txFace);
  2691.         TextSize(txSize);
  2692.         TextMode(txMode);
  2693.         SetPort(port);
  2694.  
  2695.         IWASTETextX(true, true, true, true, true);
  2696.  
  2697.         if (textLength < 256)
  2698.         {
  2699.             SetTextString(text);
  2700.         }
  2701.         else
  2702.         {
  2703.             SetTextHandle(h);                       // Set text
  2704.         }
  2705.         SetAlignCmd(alignCmd);                  // Set justification
  2706.         SetSpacingCmd(spacingCmd);              // Set line spacing
  2707.     }
  2708.     catch_all_()
  2709.     {
  2710.         TCLForgetHandle(h);
  2711.         throw_same_();
  2712.     }
  2713.     end_try_
  2714.     TCLForgetHandle(h);
  2715. #endif
  2716. }
  2717.  
  2718. /******************************************************************************
  2719.  PutTo
  2720.     CEditText compatible PutTo
  2721.  ******************************************************************************/
  2722.  
  2723. void CWASTEText::PutTo(CStream& stream)
  2724. {
  2725. #ifdef TCL_OBJECT_IO
  2726.     Handle            h;                  // Text contents
  2727.     SignedByte        state;
  2728.     short            txFont, txFace, txMode, txSize, textLength;
  2729.     Str255            fontName;
  2730.     TextStyle        theStyle;
  2731.  
  2732.     stream << spacingCmd << alignCmd << (short) 0;
  2733.     GetCharStyle(0, &theStyle);
  2734.     txFace = theStyle.tsFace;
  2735.     txMode = srcCopy; // not really supported
  2736.     txSize = theStyle.tsSize;
  2737.     h = GetTextHandle();
  2738.     textLength = GetHandleSize(h);
  2739.     stream << txFace << txMode << txSize << textLength;
  2740.  
  2741.     txFont = theStyle.tsFont;            // Save font name
  2742.     GetFontName(txFont, fontName);
  2743.     stream.PutStr255(fontName);
  2744.  
  2745.     state = HGetState(h);
  2746.     if ((state & 0x80) == 0) {            // If not already locked
  2747.         MoveHHi(h);
  2748.         HLock(h);
  2749.     }
  2750.     try_
  2751.     {
  2752.         stream.Put(*h, textLength);
  2753.     }
  2754.     catch_all_()
  2755.     {
  2756.         HSetState(h, state);
  2757.         throw_same_();
  2758.     }
  2759.     end_try_
  2760.     HSetState(h, state);
  2761.  
  2762.     CAbstractText::PutTo(stream);        // Let base class save
  2763. #endif
  2764. }
  2765.  
  2766. #else // normal version of I/O
  2767.  
  2768. /********************************************************\
  2769.  GetFrom -  read a CWASTEText from a stream
  2770. \********************************************************/
  2771.  
  2772. void CWASTEText::GetFrom(CStream& stream)
  2773. {
  2774. #ifdef TCL_OBJECT_IO
  2775.     Boolean supportObjects = false;
  2776.     Boolean supportUndo, supportDragAndDrop, outlineHighliting, drawOffscreen;
  2777.  
  2778.     stream >> spacingCmd >> alignCmd;
  2779.  
  2780.     inherited::GetFrom(stream);
  2781.  
  2782. #if WASTE_OBJECTS
  2783.     stream >> supportObjects;
  2784. #endif
  2785.     stream >> supportUndo >> supportDragAndDrop >> outlineHighliting >> drawOffscreen;
  2786.         
  2787.      volatile Handle        hText = NULL;
  2788.     volatile StScrpHandle    hStyles = NULL;
  2789.     volatile WESoupHandle    hSoup = NULL;
  2790.  
  2791.     try_
  2792.     {
  2793.         IWASTETextX(supportObjects, supportUndo, supportDragAndDrop, outlineHighliting, drawOffscreen);
  2794.         
  2795.         hText = stream.GetHandle();
  2796.         hStyles = (StScrpHandle) stream.GetHandle();
  2797.         hSoup = stream.GetHandle();
  2798.         
  2799.         HLock(hText);
  2800.         InsertWithStyleSoup(*hText, GetHandleSize(hText), hStyles, hSoup, FALSE);
  2801.         HUnlock(hText);
  2802.         
  2803.         TCLForgetHandle (hText);
  2804.         TCLForgetHandle (hStyles);
  2805.         TCLForgetHandle (hSoup);
  2806.     }
  2807.     catch_all_()
  2808.     {
  2809.         TCLForgetHandle (hText);
  2810.         TCLForgetHandle (hStyles);
  2811.         TCLForgetHandle (hSoup);
  2812.         
  2813.         throw_same_();
  2814.     }
  2815.     end_try_
  2816. #endif
  2817.  
  2818. }
  2819.  
  2820. /********************************************************\
  2821.  PutTo - write a CWASTEText to a stream
  2822. \********************************************************/
  2823.  
  2824. void CWASTEText::PutTo(CStream& stream)
  2825. {
  2826. #ifdef TCL_OBJECT_IO
  2827.     stream << spacingCmd << alignCmd;
  2828.  
  2829.     inherited::PutTo(stream);
  2830.  
  2831. #if WASTE_OBJECTS
  2832.     stream << hasObjectSupport;
  2833. #endif
  2834.     Boolean supportUndo = (WEFeatureFlag(weFUndo, weBitTest, macWE) == weBitSet);
  2835.     Boolean supportDragAndDrop = (WEFeatureFlag(weFDragAndDrop, weBitTest, macWE) == weBitSet);
  2836.     Boolean outlineHighliting = (WEFeatureFlag(weFOutlineHilite, weBitTest, macWE) == weBitSet);
  2837.     Boolean drawOffscreen = (WEFeatureFlag(weFDrawOffscreen, weBitTest, macWE) == weBitSet);
  2838.  
  2839.     stream << supportUndo << supportDragAndDrop << outlineHighliting << drawOffscreen;
  2840.     
  2841.     Handle            hText = NewHandle (0);
  2842.     StScrpHandle    hStyles = (StScrpHandle) NewHandle(0);
  2843.     WESoupHandle    hSoup = (WESoupHandle)NewHandle(0);
  2844.     long             end = WEGetTextLength(macWE);
  2845.  
  2846.     FailNIL(hSoup);
  2847.     FailNIL(hText);
  2848.     FailNIL(hStyles);
  2849.  
  2850.     try_
  2851.     {
  2852.         CopyRangeWithStyleSoup(0, end, hText, NULL, NULL);
  2853.         stream.PutHandle(hText);
  2854.         TCLForgetHandle(hText);
  2855.         
  2856.         CopyRangeWithStyleSoup(0, end, NULL, hStyles, NULL);
  2857.         stream.PutHandle((Handle) hStyles);
  2858.         TCLForgetHandle(hStyles);
  2859.         
  2860.         CopyRangeWithStyleSoup(0, end, NULL, NULL, hSoup);
  2861.         stream.PutHandle(hSoup);
  2862.         TCLForgetHandle(hSoup);
  2863.     }
  2864.     catch_all_()
  2865.     {
  2866.         TCLForgetHandle(hText);
  2867.         TCLForgetHandle(hStyles);
  2868.         TCLForgetHandle(hSoup);
  2869.         
  2870.         throw_same_();
  2871.     }
  2872.     end_try_
  2873.  
  2874. #endif
  2875. }
  2876.  
  2877. #endif // VA_COMPATIBLE_IO
  2878.  
  2879. #endif // TCL 2.0
  2880.  
  2881. /********************************************************\
  2882.  WEClickLoop - click loop routine
  2883. \********************************************************/
  2884.  
  2885. pascal Boolean CWASTEText::WEClickLoop(WEHandle hWE)
  2886. {
  2887.     Point        mouseLoc;
  2888.     LongPt        longMouse;
  2889.     CWASTEText *itsOwner = NULL;
  2890.  
  2891.     WEGetInfo(weRefCon, (Ptr)&itsOwner, hWE);
  2892. #if (TCL_VERSION) >= 0x02000000
  2893.     TCL_ASSERT_OBJECT_PTR(itsOwner);
  2894.     TCL_ASSERT(member(itsOwner, CWASTEText));
  2895. #else
  2896.     ASSERT(member(itsOwner, CWASTEText));
  2897. #endif
  2898.     
  2899.     if (itsOwner != NULL)
  2900.     {
  2901.         GetMouse(&mouseLoc);
  2902.         itsOwner->QDToFrame(mouseLoc, &longMouse);
  2903.         itsOwner->AutoScroll( &longMouse);
  2904.     }
  2905.     return(TRUE);
  2906. }
  2907.  
  2908. // static variables for the following routines
  2909. static Boolean wasActive, outlineHilite, wasGopher;;
  2910. static long selStart, selEnd;
  2911.  
  2912. /********************************************************\
  2913.  TempSelectAll -- temporarily selects all of the text
  2914.      while deactivating the text and turning off 
  2915.      outline hilighting so that the selection won't show
  2916.      up.  It can be restored by Restore selection.  This
  2917.      is useful when you want to apply something to all
  2918.      of the text without seeing all of the text flash.
  2919.      
  2920.      Note: Calls to TempSelectAll/RestoreSelection cannot
  2921.      be nested
  2922. \********************************************************/
  2923.  
  2924. void CWASTEText::TempSelectAll(void)
  2925. {
  2926.     // turn off outline highlighting temporarily
  2927.     outlineHilite = SetOutlineHighliting(false);
  2928.  
  2929.     // deactivate text
  2930.     wasActive = active;
  2931.     wasGopher = (gGopher == this);
  2932.     if (wasActive) Deactivate();
  2933.     
  2934.     // select all
  2935.     GetSelection(&selStart, &selEnd);
  2936.     SetSelection(0, 0x7FFFFFF, false);
  2937. }
  2938.     
  2939. /********************************************************\
  2940.  RestoreSelection - restores things to the way they
  2941.      were before a call to TempSelectAll()
  2942. \********************************************************/
  2943.  
  2944. void CWASTEText::RestoreSelection(void)
  2945. {
  2946.     if (wasActive) Activate();
  2947.     if (wasGopher) BecomeGopher(true);
  2948.     SetOutlineHighliting(outlineHilite);
  2949.     SetSelection(selStart, selEnd, false);
  2950. }
  2951.  
  2952. /******************************************************************************
  2953.  Specify
  2954.  
  2955.     In WASTE 1.0, if editable is changed and it's active, enable/disable TSMInput
  2956.  ******************************************************************************/
  2957.  
  2958. void CWASTEText::Specify(Boolean fEditable, Boolean fSelectable, Boolean fStylable)
  2959. {
  2960.     Boolean wasEditable = editable;
  2961.     Boolean oldWantsClicks = wantsClicks;
  2962. #if WASTE_VERSION == 0x01000000
  2963.     TSMDocumentID aTSMDocument;
  2964. #endif
  2965.     
  2966.     selectable = fSelectable;
  2967.  
  2968.     inherited::Specify(fEditable, fSelectable, fStylable);
  2969.     // don't let Specify change wantsClicks
  2970.     wantsClicks = oldWantsClicks;
  2971.  
  2972. #if WASTE_VERSION >= 0x01100000
  2973.     // use weFReadOnly flag
  2974.     if (macWE)
  2975.     {
  2976.         if (!fEditable) WEFeatureFlag(weFReadOnly, weBitSet, macWE);
  2977.         else WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  2978.  
  2979. #if WASTE_VERSION >= 0x01204004
  2980.         if (!fStylable) WEFeatureFlag(weFMonoStyled, weBitSet, macWE);
  2981.         else WEFeatureFlag(weFMonoStyled, weBitClear, macWE);
  2982. #endif
  2983.     }
  2984. #else
  2985.     if (active && wasEditable && !editable)
  2986.     {
  2987.         // if not editable, deactivate TSM so inline input won't work
  2988.         if (gUsingTSM)
  2989.         {
  2990.             if (WEGetInfo(weTSMDocumentID, (Ptr)&aTSMDocument, macWE) == noErr)
  2991.             {
  2992.                 if (aTSMDocument != NULL)
  2993.                     DeactivateTSMDocument(aTSMDocument);
  2994.             }
  2995.         }
  2996.     }
  2997.  
  2998.     if (active && !wasEditable && editable)
  2999.     {
  3000.         // if editable, activate TSM so inline input will work
  3001.         if (gUsingTSM)
  3002.         {
  3003.             if (WEGetInfo(weTSMDocumentID, (Ptr)&aTSMDocument, macWE) == noErr)
  3004.             {
  3005.                 if (aTSMDocument != NULL)
  3006.                     ActivateTSMDocument(aTSMDocument);
  3007.             }
  3008.         }
  3009.     }
  3010. #endif
  3011. }
  3012.  
  3013. /******************************************************************************
  3014.  AdjustCursor
  3015.  
  3016.     Use WEAdjustCursor to set the cursor
  3017.  ******************************************************************************/
  3018.  
  3019. void CWASTEText::AdjustCursor(Point where, RgnHandle mouseRgn)
  3020. {
  3021.     Point        wTopLeft;
  3022.  
  3023.     if (wantsClicks && selectable)
  3024.     {
  3025.         Prepare();
  3026.     
  3027.         // convert back to global coords
  3028.         wTopLeft = topLeft((**((WindowPeek)GetWindow()->macPort)->contRgn).rgnBBox);
  3029.         where.h += wTopLeft.h;
  3030.         where.v += wTopLeft.v;
  3031.  
  3032.         WEAdjustCursor(where, mouseRgn, macWE);
  3033.     }
  3034. }
  3035.  
  3036. /******************************************************************************
  3037.  InhibitRecal
  3038.     turn on or off inhibition of recalibration, returns old value
  3039.  ******************************************************************************/
  3040.  
  3041. Boolean CWASTEText::InhibitRecal(Boolean inhibit)
  3042. {
  3043.     return WEFeatureFlag(weFInhibitRecal, inhibit ? weBitSet : weBitClear, macWE);
  3044. }
  3045.  
  3046. /*****************************************************************************\
  3047.  RecalcText - calls WECalText()
  3048.      You should only need to call this if you turn use InhibitRecal()
  3049. \*****************************************************************************/
  3050.  
  3051. //void CWASTEText::RecalcText(void)
  3052.  
  3053. /******************************************************************************\
  3054.  InhibitRedraw
  3055.     turn on or off inhibition of redrawing
  3056. \******************************************************************************/
  3057.  
  3058. Boolean CWASTEText::InhibitRedraw(Boolean inhibit)
  3059. {
  3060.     // ability to inhibit redraw was introduced in WASTE 1.2a3
  3061.  
  3062. #if WASTE_VERSION >= 0x01204003
  3063.     return WEFeatureFlag(weFInhibitRedraw, inhibit ? weBitSet : weBitClear, macWE);
  3064. #else
  3065.     return 0;
  3066. #endif
  3067. }
  3068.  
  3069. /******************************************************************************\
  3070.   SetLineWidth -- sets the line width
  3071.       contributed by Jan Petersen
  3072. \******************************************************************************/
  3073.  
  3074. void CWASTEText::SetLineWidth(short aLineWidth)
  3075. {
  3076.     lineWidth = aLineWidth;
  3077.     CalcWERects();
  3078. }
  3079.  
  3080. #if WASTE_OBJECTS
  3081. /******************************************************************************
  3082.  InsertPicture
  3083.     Insert a picture
  3084.  ******************************************************************************/
  3085.  
  3086. void CWASTEText::InsertPicture(PicHandle pHandle, Boolean fRedraw)
  3087. {
  3088.     Point zeroPoint = {0, 0};
  3089.     Boolean        saveAllocState;
  3090.     OSErr        err;
  3091.     Boolean        wasReadOnly;
  3092.     Boolean        oldRedraw;
  3093.  
  3094.     Prepare();
  3095.  
  3096.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  3097.  
  3098.     if (!ReallyVisible())
  3099.         SetOrigin(-10000, -10000);
  3100.     CheckInsertion((*pHandle)->picSize, 0, TRUE);
  3101.     saveAllocState = SetAllocation(kAllocCanFail);
  3102.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  3103.     err = WEInsertObject(kTypePicture, (Handle)pHandle, zeroPoint, macWE);
  3104.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  3105.     SetAllocation(saveAllocState);
  3106.  
  3107.     AdjustBounds();
  3108.  
  3109.     if (!fRedraw) InhibitRedraw(oldRedraw);
  3110.  
  3111.     FailOSErr(err);
  3112. }
  3113.  
  3114. /******************************************************************************
  3115.  InsertSound
  3116.     Insert a sound
  3117.  ******************************************************************************/
  3118.  
  3119. void CWASTEText::InsertSound(Handle sHandle, Boolean fRedraw)
  3120. {
  3121.     Point zeroPoint = {0, 0};
  3122.     Boolean        saveAllocState;
  3123.     OSErr        err;
  3124.     Boolean        wasReadOnly;
  3125.     Boolean        oldRedraw;
  3126.  
  3127.     Prepare();
  3128.  
  3129.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  3130.  
  3131.     if (!ReallyVisible())
  3132.         SetOrigin(-10000, -10000);
  3133.     CheckInsertion(GetHandleSize(sHandle), 0, TRUE);
  3134.     saveAllocState = SetAllocation(kAllocCanFail);
  3135.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  3136.     err = WEInsertObject(kTypeSound, sHandle, zeroPoint, macWE);
  3137.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  3138.     SetAllocation(saveAllocState);
  3139.  
  3140.     AdjustBounds();
  3141.  
  3142.     if (!fRedraw) InhibitRedraw(oldRedraw);
  3143.  
  3144.     FailOSErr(err);
  3145. }
  3146.  
  3147. #if WASTE_OBJECT_ARCHIVE
  3148. /******************************************************************************
  3149.  InsertFSSpec
  3150.     Insert a file
  3151.  ******************************************************************************/
  3152.  
  3153. void CWASTEText::InsertFSSpec(FSSpec *theFSSpec, Boolean fRedraw)
  3154. {
  3155.     Point zeroPoint = {0, 0};
  3156.     Boolean        saveAllocState;
  3157.     OSErr        err;
  3158.     Boolean        wasReadOnly;
  3159.     Handle        fsHandle;
  3160.     Boolean        oldRedraw;
  3161.  
  3162.     Prepare();
  3163.  
  3164.     if (!fRedraw) oldRedraw = InhibitRedraw(true);
  3165.  
  3166.     if (!ReallyVisible())
  3167.         SetOrigin(-10000, -10000);
  3168.     fsHandle = NewHandle(sizeof(FSSpec));
  3169.     FailNIL(fsHandle);
  3170.     *((FSSpec *)*fsHandle) = *theFSSpec;
  3171.     saveAllocState = SetAllocation(kAllocCanFail);
  3172.     wasReadOnly = WEFeatureFlag(weFReadOnly, weBitClear, macWE);
  3173.     err = WEInsertObject(flavorTypeHFS, fsHandle, zeroPoint, macWE);
  3174.     WEFeatureFlag(weFReadOnly, wasReadOnly, macWE);
  3175.     SetAllocation(saveAllocState);
  3176.  
  3177.     AdjustBounds();
  3178.  
  3179.     if (!fRedraw) InhibitRedraw(oldRedraw);
  3180.  
  3181.     FailOSErr(err);
  3182. }
  3183. #endif // WASTE_OBJECTS
  3184.  
  3185. #endif // WASTE 1.1
  3186.  
  3187. #if WASTE_VERSION >= 0x01100000
  3188.  
  3189. /******************************************************************************
  3190.  DoDrag
  3191.     
  3192.     See if a drag is started, and if so, handle click-through properly
  3193.  ******************************************************************************/
  3194.  
  3195. Boolean CWASTEText::DoDrag(EventRecord *theEvent, Point where)
  3196. {
  3197.     long selStart, selEnd;
  3198.     RgnHandle selRgn;
  3199.  
  3200.     if (!gHasDragAndDrop) return false;
  3201.     
  3202.     Prepare();
  3203.  
  3204.     WEGetSelection(&selStart, &selEnd, macWE);
  3205.     selRgn = WEGetHiliteRgn(selStart, selEnd, macWE);
  3206.     if (PtInRgn(where, selRgn) && WaitMouseMoved(theEvent->where))
  3207.     {
  3208.         // doing a drag -- just call DoClick now...
  3209.         DoClick(where, theEvent->modifiers, theEvent->when);
  3210.         return true;
  3211.     }
  3212.     return false;
  3213. }
  3214.  
  3215. /******************************************************************************
  3216.  GetUndoInfo - get information about what's in WASTE's undo stack
  3217.  ******************************************************************************/
  3218.  
  3219. WEActionKind CWASTEText::GetUndoInfo(Boolean *redoFlag)
  3220. {
  3221.     return WEGetUndoInfo(redoFlag, macWE);
  3222. }
  3223.  
  3224. /******************************************************************************
  3225.  DoUndo - perform undo operation
  3226.  ******************************************************************************/
  3227.  
  3228. void CWASTEText::DoUndo(void)
  3229. {
  3230.     FailOSErr(WEUndo(macWE));
  3231. }
  3232.  
  3233.  
  3234. #endif // WASTE 1.1
  3235.  
  3236. /*****************************************************************************\
  3237.  WriteToFile - saves the WASTE pane to an open CDataFile
  3238.      in a format similar to SimpleText, but with an additional 'SOUP' resource
  3239.      Added in WASTE-TCL 2.0
  3240. \*****************************************************************************/
  3241.  
  3242. void CWASTEText::WriteToFile(CDataFile *dataFile)
  3243. {
  3244.     Handle volatile theData = NULL;
  3245.     StScrpHandle volatile theStyl = NULL;
  3246. #if WASTE_VERSION >= 0x01100000
  3247.     WESoupHandle volatile theSoup = NULL;
  3248. #endif
  3249.     CResFile    *volatile resFile = NULL;
  3250.     Handle        h;
  3251.     FSSpec        theSpec;
  3252.     short         oldRes = CurResFile();
  3253.     
  3254.     try_
  3255.     {
  3256.         theData = NewHandle(0);
  3257.         FailNIL(theData);
  3258.         theStyl = (StScrpHandle)NewHandle(0);
  3259.         FailNIL(theStyl);
  3260. #if WASTE_VERSION >= 0x01100000
  3261.         theSoup = (WESoupHandle)NewHandle(0);
  3262.         FailNIL(theSoup);
  3263.         CopyRangeWithStyleSoup(0, 0x7FFFFFF, theData, theStyl, theSoup);
  3264. #else
  3265.         CopyRangeWithStyle(0, 0x7FFFFFFF, theData, theStyl);
  3266. #endif
  3267.         dataFile->WriteAll(theData);
  3268.         TCLForgetHandle(theData);            
  3269.         //dataFile->Close();
  3270.  
  3271.         // write styl resource
  3272.         resFile = new CResFile();
  3273.         FailNIL(resFile);
  3274.         dataFile->GetFSSpec(&theSpec);
  3275.         resFile->SpecifyFSSpec(&theSpec);
  3276.         if (!resFile->HasResFork())
  3277.         {
  3278.             resFile->CreateNew('xxxx', 'xxxx');
  3279.         }
  3280.         resFile->Open(fsWrPerm);
  3281.         // see if resource already exists
  3282.         h = Get1IndResource('styl', 1);
  3283.         if (h==NULL) // doesn't exist
  3284.         {
  3285.             AddResource((Handle)theStyl, 'styl', 128, "\p");
  3286.             FailResError();
  3287.         }
  3288.         else
  3289.         {
  3290.             // change what's there
  3291.             SetHandleSize(h, 0);
  3292.             HLock((Handle)theStyl);
  3293.             HandAndHand((Handle)theStyl, h);
  3294.             ChangedResource(h);
  3295.             TCLForgetHandle((Handle &)theStyl);
  3296.         }
  3297.         resFile->Update();
  3298.         if (h) ReleaseResource(h);
  3299.         
  3300. #if WASTE_VERSION >= 0x01100000
  3301.         // write soup resource
  3302.         // see if resource already exists
  3303.         h = Get1IndResource(kTypeSoup, 1);
  3304.         if (h==NULL) // doesn't exist
  3305.         {
  3306.             AddResource((Handle)theSoup, kTypeSoup, 128, "\p");
  3307.             FailResError();
  3308.         }
  3309.         else
  3310.         {
  3311.             // change what's there
  3312.             SetHandleSize(h, 0);
  3313.             HLock((Handle)theSoup);
  3314.             HandAndHand((Handle)theSoup, h);
  3315.             ChangedResource(h);
  3316.             TCLForgetHandle((Handle &)theSoup);
  3317.         }
  3318.         resFile->Update();
  3319.         if (h) ReleaseResource(h);
  3320. #endif        
  3321.         resFile->Close();
  3322.         TCLForgetObject(resFile);
  3323.         UseResFile(oldRes); // use old resource file
  3324.     }
  3325.     catch_all_()
  3326.     {
  3327.         TCLForgetObject(resFile);
  3328.         TCLForgetHandle(theData);
  3329.         TCLForgetHandle(theStyl);
  3330. #if WASTE_VERSION >= 0x01100000
  3331.         TCLForgetHandle(theSoup);
  3332. #endif
  3333.         UseResFile(oldRes); // use old resource file
  3334.         throw_same_();
  3335.     }
  3336.     end_try_
  3337. }
  3338.  
  3339. /*****************************************************************************\
  3340.  ReadFromFile - reads from an opened CDataFile to the WASTE pane.  The file is 
  3341.      in a format similar to SimpleText, but with an additional 'SOUP' resource
  3342.      Added in WASTE-TCL 2.0
  3343. \*****************************************************************************/
  3344.  
  3345. void CWASTEText::ReadFromFile(CDataFile *theFile)
  3346. {
  3347.     Handle        theData = NULL;
  3348.     OSErr        theError;
  3349.     CResFile    *resFile = NULL;
  3350.     StScrpHandle stylHandle = NULL;
  3351.     WESoupHandle soupHandle = NULL;
  3352.     short         oldRes = CurResFile();
  3353.     FSSpec        theSpec;
  3354.  
  3355.      try_
  3356.      {
  3357.         theData = theFile->ReadAll();
  3358.         theFile->GetFSSpec(&theSpec);
  3359.  
  3360.         // check for styl, soup resources resource
  3361.         resFile = new CResFile();
  3362.         resFile->SpecifyFSSpec(&theSpec);
  3363.         if (resFile->HasResFork())
  3364.         {
  3365.             resFile->Open(fsRdPerm);
  3366.             
  3367.             resFile->MakeCurrent(); // Use the resource file.
  3368.     
  3369.             // •• style ••
  3370.             stylHandle = (StScrpHandle)Get1IndResource('styl', 1); // get the resource
  3371.             if (stylHandle)
  3372.             {
  3373.                 DetachResource((Handle)stylHandle);
  3374. #if WASTE_VERSION < 0x01100000
  3375.                 // fix height=0 lines
  3376.                 long i, nStyles;
  3377.                 nStyles = (*stylHandle)->scrpNStyles;    
  3378.                 for(i=0; i<nStyles; i++)
  3379.                     if ((*stylHandle)->scrpStyleTab[i].scrpSize==0)
  3380.                         (*stylHandle)->scrpStyleTab[i].scrpSize = 12;
  3381. #endif
  3382.             }
  3383.             // •• soup ••
  3384.             soupHandle = (WESoupHandle)Get1IndResource(kTypeSoup, 1); // get the resource
  3385.             if (soupHandle)
  3386.             {
  3387.                 DetachResource((Handle)soupHandle);
  3388.             }
  3389.             resFile->Close();
  3390.         }
  3391.         TCLForgetObject(resFile);
  3392.     
  3393.         HLock(theData);
  3394.         InsertWithStyleSoup(*theData, GetHandleSize(theData),
  3395.             stylHandle, soupHandle, true);
  3396.         HUnlock(theData);
  3397.  
  3398.         TCLForgetHandle(theData);
  3399.         TCLForgetHandle((Handle &)stylHandle);
  3400.         TCLForgetHandle((Handle &)soupHandle);
  3401.         UseResFile(oldRes); // use old resource file
  3402.  
  3403.     }
  3404.     catch_all_()
  3405.     {
  3406.         TCLForgetObject(resFile);
  3407.         TCLForgetHandle(theData);
  3408.         TCLForgetHandle((Handle &)stylHandle);
  3409.         TCLForgetHandle((Handle &)soupHandle);
  3410.         UseResFile(oldRes); // use old resource file
  3411.  
  3412.         throw_same_();
  3413.     }
  3414.     end_try_
  3415.     
  3416. }
  3417.  
  3418. /******************************************************************************
  3419.  ScrollToRange
  3420.  
  3421.         Scroll the text so that the specified is visible within
  3422.         the frame
  3423.  
  3424.         Based on CAbstractText::ScrollToSelection
  3425.  ******************************************************************************/
  3426.  
  3427. void CWASTEText::ScrollToRange(long rangeStart, long rangeEnd)
  3428. {
  3429.     long    startLine, endLine;
  3430.     short    hSpan;
  3431.     short    vSpan;
  3432.     LongPt    selPos, selPt;
  3433.     long    vStart, vEnd;
  3434.  
  3435.     startLine = FindLine(rangeStart);
  3436.  
  3437.     if (rangeStart == rangeEnd) {
  3438.         endLine = startLine;
  3439.     } else {
  3440.         endLine = FindLine(rangeEnd);
  3441.     }
  3442.  
  3443.         // calculate frame span in pixels
  3444.     hSpan = (frame.right - frame.left) / hScale;
  3445.     vSpan = (frame.bottom - frame.top) / vScale;
  3446.  
  3447.         // set vStart to the bottom of the first selected line
  3448.     vStart = GetHeight(0, startLine+1) / vScale;
  3449.  
  3450.         // set vEnd to the top of the last selected line
  3451.     vEnd = endLine > 0 ? GetHeight(0, endLine) / vScale : 0;
  3452.     
  3453.     selPos.v = position.v;
  3454.     if (vStart >= position.v + vSpan)
  3455.         selPos.v = vStart - vSpan;
  3456.     else if (vEnd < position.v)
  3457.         selPos.v = vEnd;
  3458.  
  3459.     if (!scrollHoriz)
  3460.         selPos.h = position.h;
  3461.     else
  3462.     {
  3463.         if (selPos.v == vEnd)
  3464.             GetCharPoint(rangeEnd, &selPt);
  3465.         else
  3466.             GetCharPoint(rangeStart, &selPt);
  3467.         selPos.h = Max(0, (selPt.h - frame.right + frame.left) / hScale);
  3468.     }
  3469.  
  3470.     if (selPos.v != position.v || selPos.h != position.h)
  3471.     {
  3472.             // Note: It is ok to call HideSelection(FALSE) because
  3473.             // ScrollToRange is never called during printing
  3474.  
  3475.         HideSelection(TRUE, TRUE);
  3476.         ScrollTo(&selPos, TRUE);
  3477.         HideSelection(FALSE, TRUE);
  3478.     }
  3479. }
  3480.  
  3481.